分析SQL执行带来的开销是优化SQL的重要手段。在MySQL数据库中,可以通过配置profiling参数来启用SQL剖析。该参数可以在全局和session级别来设置。对于全局级别则作用于整个MySQL实例,而session级别紧影响当前session。该参数开启后,后续执行的SQL语句都将记录其资源开销,诸如IO,上下文切换,CPU,Memory等等。根据这些开销进一步分析当前SQL瓶颈从而进行优化与调整。本文描述了如何使用MySQL profile。
查看 show profile
是否已经开启
1
| SHOW VARIABLES LIKE 'profiling'
|

设置 show profile
开启
执行sql语句
这里执行SQL语句只是为了看 show profile
能不能记录SQL执行的情况,结果不是重点。
这里主要注意的是最后执行的时间,因为这里执行的时间在 show profile
中会被统计出来。
第一条

第二条
我这里的 emp
表中有50万条记录
1
| SELECT * FROM emp GROUP BY id/10 LIMIT 200000;
|

第三条
1
| select * from emp left outer join dept on emp.`deptno` = dept.`deptno`;
|

第四条
1
| SELECT * FROM dept LEFT OUTER JOIN emp ON emp.`deptno` = dept.`deptno`;
|

查看 show profile
记录

Duration
是执行时间
使用 show profile
参数查看详情
一、具体参数

二、使用
1
2
| show profile cpu,block io for query 3;
show profile cpu,block io for query 4;
|

这里发现Sending data
耗费的时间格外的多,就将查询到的Sending data
的解释贴在这里是Sending data
Sending data
这个状态的名称很具有误导性,所谓的Sending data
并不是单纯的发送数据,而是包括“收集 + 发送 数据”。
这里的关键是为什么要收集数据,原因在于:mysql
使用“索引”完成查询结束后,mysql
得到了一堆的行id
,如果有的列并不在索> > 引中,mysql
需要重新到“数据行”上将需要返回的数据读取出来返回个客户端。
三、 这里将查询的某些参数去掉在执行查询
这里将之前的 *
换成了具体的几个参数
发现 Sending data
比之前少了很多
1
| select empno,dept.deptno,dname from emp left outer join dept on emp.`deptno` = dept.`deptno`;
|

四、还有哪些需要格外注意的项

最后补充一个知识点,是可以记录所有执行过的sql的信息-全局查询日志
这里只推荐在测试环境使用
开启全局查询日志
1
2
| SET GLOBAL general_log=1; --设置开启全局查询日志
SET GLOBAL log_output='TABLE'; --设置将查询日志输出到表中,mysql.general_log表
|
查看全局查询日志
执行几条sql之后,查看全局查询日志
1
| select * from mysql.general_log;
|
