看本篇之前建议先看上篇:MySQL优化:定位慢查询的两种方法以及使用explain分析SQL
在上一节我们学习了定位慢SQL及使用explain分析慢SQL,我们也提到了分析慢SQL还有showprofile和trace等方法,本节就重点补充学习这两种方法。
showprofile分析慢查询
NO.1使用profile分析慢查询
大致步骤:
确定这个MySQL版本是否支持profile;确定profile是否关闭;如果关闭开启profile;在服务器端发送要执行的SQL;查看执行完SQL的queryid;通过queryid查看SQL的每个状态及耗时时间;停止profile;
获取profile使用helpprofile即可
mysqlhelpprofile;
1.1确定是否支持profile
mysqlselect
have_profiling;如果结果是YES表示支持。
1.2查看profiling状态
mysqlselect
profiling;0表示关闭,1表示开启,默认是关闭的。
使用如下命令开启:mysqlsetprofiling=1;
1.3执行要分析的sql语句
mysqlselect*fromtest_tablewhered=;
执行完成SQL后再执行:showprofiles;得到profileid。
1.4根据profileid查询指定SQL执行详情
通过showprofileforqueryid可看到执行过的SQL每个状态和消耗时间:
MySQL[test]showprofileforquery1;
通过以上结果,可以确定SQL执行过程具体在哪个过程耗时比较久,从而更好地进行SQL优化与调整。
注意:“showprofiles”已弃用,SHOWPROFILES将来会被PerformanceSchema替换掉,但是现在还是非常非常实用的,8.0目前还在支持中。
小计:实用showprofile可以直接查看上一条SQL语句的执行开销
MySQL[test]showprofile;
NOTE:showprofile自身不会产生Profiling。
查看指定SQL的CPU开销:MySQL[test]showprofilecpuforquery1;
查询指定SQL的内存开销:MySQL[test]showprofilememoryforquery1;
小技巧:给大家分享一条SQL,查询某条SQL开销并且按照耗时倒叙排序
SET
query_id=1;//设置要查询的profileid,然后执行如下SQL即可SELECTSTATE,SUM(DURATION)ASTotal_R,ROUND(*SUM(DURATION)/(SELECTSUM(DURATION)FROMINFORMATION_SCHEMA.PROFILINGWHEREQUERY_ID=query_id),2)ASPct_R,COUNT(*)ASCalls,SUM(DURATION)/COUNT(*)ASR/CallFROMINFORMATION_SCHEMA.PROFILINGWHEREQUERY_ID=query_idGROUPBYSTATEORDERBYTotal_RDESC;注意:Mysql所有的profile都被记录到了information_schema.profiling表。
1.5关闭profile
mysqlsetprofiling=off;
trace分析SQL优化器
从前面学到了explain可以查看SQL执行计划,但是无法知道它为什么做这个决策,如果想确定多种索引方案之间是如何选择的或者排序时选择的是哪种排序模式,有什么好的办法吗?
从MySQL5.6开始,可以使用trace查看优化器如何选择执行计划。
通过trace,能够进一步了解为什么优化器选择A执行计划而不是选择B执行计划,或者知道某个排序使用的排序模式,帮助我们更好地理解优化器行为。
如果需要使用,先开启trace,设置格式为JSON,再执行需要分析的SQL,最后查看trace分析结果(在information_schema.OPTIMIZER_TRACE中)。
注意:开启该功能,会对MySQL性能有所影响,因此只建议分析问题时临时开启。
这里利用我们上篇:MySQL优化:定位慢查询的两种方法以及使用explain分析SQL中创建的数据表test_table;
在test_table中除了d字段,abc字段都有索引。执行如下sql
explainselect*fromtest_tablewherea=andb=orderbya;
通过上面执行计划中key这个字段可以看出,该语句使用的是b字段的索引idx_a。实际表t1中,a、b两个字段都有索引,为什么条件中有这两个索引字段却偏偏选了a字段的索引呢?这时就可以使用trace进行分析。
大致步骤如下:
开启trace分析器执行要查询的sql查看分析结果关闭trace分析器
NO.1开启trace分析器
MySQL[test]setsessionoptimizer_trace=enabled=on;
NO.2执行要查询的SQL
MySQL[test]select*fromtest_tablewherea=andb=orderbya;
NO.3查询分析结果
MySQL[test]SELECT*FROMinformation_schema.OPTIMIZER_TRACE\G
注意:在返回的steps数组中可以查看详细mysql都干了什么。
不好意思,因为排版导致内容太长大家可以百度一下参数含义。
NO.4关闭trace分析器
mysqlsetsessionoptimizer_trace=enabled=off;
TRACE字段中整个文本大致分为三个过程
准备阶段:对应文本中的join_preparation优化阶段:对应文本中的join_optimization执行阶段:对应文本中的join_execution
使用时,重点