对于SQL优化,我们经常使用explain命令,而除了explain以外,profiling和Optimizer Trace也很有帮助。
一、profiling
explain只是看到SQL的预估执行计划,如果要了解SQL真正的执行线程状态及消耗的时间,需要使用profiling。
还有一个区别就是:explain是SQL执行前生成的,不会真正执行SQL;而profiling是SQL执行后生成,SQL被真正执行后产生的结果。
开启profiling参数后,后续执行的SQL语句都会记录其资源开销,包括IO、上下文切换、CPU、内存等等,我们可以根据这些开销进一步分析当前慢SQL的瓶颈再进一步进行优化。
1、开启参数,打开分析。
set session profiling=1;
2、执行你的SQL。
3、查看刚才执行SQL的语句分析。
show profiles;
4、当会话执行过多次SQL,可以根据query id查看指定SQL的语句分析。
show profile for query 1;
5、查看SQL1相关的所有分析,包括CPU、内存、IO等。
show profile ALL for query 1;
6、也可查看SQL1特定的资源开销分析,如CPU。
show profile cpu for query 1;
7、关闭分析
set session profiling=0;
注意:
1、该参数可以在全局和session级别来设置。对于全局级别则作用于整个MySQL实例,而session级别影响当前session。通常不建议开启全局参数,对实例性能影响较大,建议需要用的时候开启会话级即可。
2、show profiles会显示最近发给服务器的多条语句,条数由变量profiling_history_size定义,默认是15。如果我们需要看单独某条SQL的分析,可以show profile查看最近一条SQL的分析,也可以使用show profile for query id(其中id就是show profiles中的Query_ID)查看具体一条的SQL语句分析。
二、Optimizer Trace
profile只能查看到SQL的执行耗时,但是无法看到SQL真正执行的过程信息,即不知道MySQL优化器是如何选择执行计划。
在MySQL 5.6版本之后,我们可以使用Optimizer Trace,它可以跟踪执行语句的解析优化执行的全过程。
我们可以使用set optimizer_trace="enabled=on"打开开关,接着执行要跟踪的SQL,最后执行select * from information_schema.optimizer_trace跟踪,如下:
大家可以查看分析其执行树,会包括三个阶段:
join_preparation:准备阶段
join_optimization:分析阶段
join_execution:执行阶段
基于成本的优化主要集中在 join_optimization 阶段:
对于单表查询来说:主要关注join_optimization阶段的"rows_estimation"(预估不同单表访问方法的访问成本)这个过程,这个过程深入分析了对单表查询的各种执行方案的成本。
对于多表连接查询来说:需要关注join_optimization阶段的"considered_execution_plans"(分析各种可能的执行计划及成本)这个过程,这个过程里会写明各种不同的连接方式所对应的成本。
优化器最终会选择成本最低的那种方案来作为最终的执行计划,也就是我们使用 explain 语句所展现出的那种方案。
三、优化措施
通过explain、profiling和Optimizer Trace确认了SQL性能瓶颈,就可以采取对应的优化措施。
多数慢SQL都跟索引有关,比如不加索引,索引不生效、不合理等,这时候,我们可以优化索引;
我们还可以优化SQL语句,比如一些in元素过多问题(分批),深分页问题(基于上一次数据过滤等),进行时间分段查询;
SQL没办法很好优化,可以改用ES的方式,或者数仓;
如果单表数据量过大导致慢查询,则可以考虑分库分表;
如果数据库在刷脏页导致慢查询,考虑是否可以优化一些参数,跟DBA讨论优化方案;
如果存量数据量太大,考虑是否可以让部分数据归档。
全文完,希望可以帮到正在阅读的你,如果觉得有帮助,可以分享给你身边的朋友,同事,你关心谁就分享给谁,一起学习共同进步~~~
❤ 欢迎关注我的公众号【凡尘读书楼】,一起学习新知识!
————————————————————————————
公众号:凡尘读书楼
墨天轮:https://www.modb.pro/u/399450
知识星球 :凡尘dba人生有限公司
————————————————————————————