1. 通过SHOW STATUS获取更多信息
在调试mysql语句时,如果执行计划不能提供足够的信息支持判断,可以通过在语句执行前执行FLUSH STATUS,执行完语句后执行SHOW STATUS LIKE 获取更多信息,例如:
SHOW STATUS WHERE Variable_name LIKE 'Handler%' OR variable_name LIKE 'Created%';其执行部分结果解释如下:
属性 | 释义 |
Created_tmp_disk_tables | 语句执行时,Mysql创建的磁盘临时表个数;越少越好 |
Created_tmp_files | 语句执行时,Mysql创建的临时文件个数; |
Created_tmp_tables | 语句执行时,Mysql创建的临时表总个数;越少越好 |
Handler_read_first | 读取第一条索引的次数; 此值越高,表明Mysql进行了多次的全索引扫描(full index scan);而当数据在磁盘不在内存中时,全索引扫描通常会导致许多随机读(random read),这通常比全表扫描(full table scan)采用的顺序扫描性能更差; |
Handler_read_key | 通过索引读取数据的次数; 此值越高表示查询正确地走了索引; |
Handler_read_next | 通过索引顺序读取下一行的次数;当出现索引覆盖扫描或者通过在索引列限制了范围时,该次数会增加; |
Handler_read_prev | 通过索引顺序读取前一行的次数;这种读取方式主要用于对ORDER BY … DESC 语句的优化中 |
Handler_read_rnd | 通过固定的位置读取一行数据的次数;越低越好; 通常在需要对结果排序时,此值会比较高; 表明可能存在全表扫描或者不恰当的join |
Handler_read_rnd_next | 通过直接读取数据文件获取下一行数据的次数;越低越好; 通常在进行数据扫描时,此值会比较高;// TODO 通常表明索引设置不当或者查询未有效利用索引; |
Handler_write | 向表中插入数据的次数; 在生成临时表的查询中,此值表示临时表的数据量大小; |
2. 通过查看PROFILE获取更多信息
Mysql 的profile保存了当前会话若干语句在执行时所使用资源的情况,通过会话级的参数profiling控制是否保存profile信息,可以通过以下语句打开(下述的方法将在将来的版本中不再支持,官方建议通过Performanc Schema进行替代):
set profiling=1;
打开会话profile后执行语句,mysql会保留该信息,可以通过show profiles查看目前记录了profile信息的查询,以query_id标识顺序。然后可以通过如下语句获取某条语句的profile信息:
show profile (cpu) for query query_id;
示例的结果如下,duration列出各阶段耗时,CPU_user及CPU_system分别列出用户态和系统态的CPU耗时。
Status | Duration | CPU_user | CPU_system |
starting | 0.000044 | 0 | 0 |
checking permissions | 0.000005 | 0 | 0 |
Opening tables | 0.000019 | 0 | 0 |
init | 0.000009 | 0 | 0 |
System lock | 0.000054 | 0 | 0 |
optimizing | 0.000035 | 0 | 0 |
statistics | 0.000012 | 0 | 0 |
preparing | 0.000009 | 0 | 0 |
executing | 0.000002 | 0 | 0 |
Sending data | 0.014502 | 0.024 | 0 |
end | 0.000012 | 0 | 0 |
query end | 0.000005 | 0 | 0 |
closing tables | 0.000009 | 0 | 0 |
freeing items | 0.000155 | 0 | 0 |
cleaning up | 0.000014 | 0 | 0 |