庹永泽 发表于 2023-10-11 16:33:21

定位SQL慢查询

一、概念


[*]MySQL的慢查询(慢查询日志):是MySQL提供的一种日志记录,用来记录在MySQL中响应时间超过阈值的语句。
[*]具体环境中,运行时间超过long_query_time值的SQL语句,则会被记录到慢查询日志中。long_query_time的默认值为10,意思是记录运行10秒以上的语句。
[*]默认情况下,MySQL数据库并不启动慢查询日志,需要手动来设置这个参数。(如果不是调优需要的话,一般不建议启动该参数,因为开启慢查询日志会或多或少带来一定的性能影响)
慢查询日志支持将日志记录写入文件和数据库表。
二、在数据库中设置SQL慢查询


[*]开启慢查询

[*]方式一:
修改配置文件。在 my.ini 增加几行:**主要是慢查询的定义时间(超过2秒就是慢查询),以及慢查询log日志记录( slow_query_log)

;定义查过多少秒的查询算是慢查询(比如2秒)
long_query_time=2

;5.0、5.1等版本配置如下选项
log_slow_queries='mysql_slow_query.log'
;5.5以上版本配置如下选项
slow_query_log='ON'
slow_query_log_file='mysql_slow_query.log'

;记录没有使用索引查询语句
log-queries-not-using-indexeMySQL和慢查询相关的系统变量如下:
参数含义slow_query_log是否启用慢查询日志, ON为启用,OFF为没有启用,默认为OFFlog_output日志输出位置,默认为FILE,即保存为文件,若设置为TABLE,则将日志记录到mysql.show_log表中,支持设置多种格式slow_query_log_file指定慢查询日志文件的路径和名字long_query_time执行时间超过该值才记录到慢查询日志,单位为秒,默认为10
[*]方式二:
通过MySQL数据库开启慢查询。
mysql>set global slow_query_log = ON;
mysql>set global long_query_time = 3600;
mysql>set global log_queries_not_using_indexes = ON;

[*]分析慢查询日志
直接分析mysql慢查询日志 ,利用explain关键字可以模拟优化器执行SQL查询语句,来分析sql慢查询语句
explain SQL语句比如:
​                explain的参数:
输出字段含义id执行编号,标志select所属的行。如果在语句中没有子查询或关联查询,只有唯一的select,每行都将显示1。否则内层的select语句一般会顺序编号,在嵌套查询中id越大的语句越先执行。select_type显示本行是简单或复杂select。
simple:简单子查询,不包含子查询和union
primary:包含union或者子查询,最外层的部分标记为primary
subquery:一般子查询中的子查询被标记为subquery,也就是子查询中第一个select语句
derived:派生表--该临时表是从子查询中派生出来的,也就是位于select列表中的查询
union:位于union中第二个及其以后的子查询被标记为union,第一个就被标记为primary如果是位于from中则标记为derived
union result:用来从匿名临时表里检索结果的select被标记为union result
dependent union:顾名思义,首先需要满足union的条件,及union中第二个以及后面的select语句,同时该语句依赖外部的查询
dependent subquery: 子查询中第一个select语句,且该语句依赖外部的查询table对应行正在访问哪一个表,表名或者别名。
·关联查询优化器会为查询选择关联顺序,左侧深度优先
·当form中有子查询的时候,表名是derivedN的形式,N指向子查询,也就是explain结果中的下一列
·当有union result的时候,表名是union 1,2等的形式,1,2表示参与uion的query idtype访问类型,是较为重要的一个指标,结果值从好到坏依次是:
system>const>eq_ref>ref>fulltext>ref_or_null>index_merge>unique_subquery>index_subquery>range>index>ALL,一般来说,得保证查询至少达到range级别,最好能达到ref
访问类型详解:
ALL:最坏的情况,全表扫描
index:和全表扫描一样。只是扫描表的时候按照索引次序进行而不是行。主要优点就是避免了排序,但是开销仍然非常大。如在Extra列看到Using index,说明正在使用覆盖索引,只扫描索引的数据,它比按索引次序全表扫描的开销要小很多
range:范围扫描,一个有限制的索引扫描。key列显示使用了哪个索引。当使用=、、>、>=、 show processlist\G``*************************** 10. row ***************************`   `Id: 7651833`   `User: one`   `Host: 192.168.1.251:52154`   `db: ops`   `Command: Query`   `Time: 3``State: User sleep``Info: select sleep(10)``......``10 rows in set (0.00 sec)`Time表示执行时间,Info表示SQL语句。

参考资料:https://zhuanlan.zhihu.com/p/149338523#:~:text=MySQL的慢查询,全名是慢查询日志,是MySQL提供的一种日志记录,用来记录在MySQL中响应时间超过阀值的语句。,具体环境中,运行时间超过long_query_time值的SQL语句,则会被记录到慢查询日志中。 long_query_time的默认值为10,意思是记录运行10秒以上的语句。
https://www.jianshu.com/p/7c9e2c479c15

来源:https://www.cnblogs.com/Enid/p/17757370.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 定位SQL慢查询