什么是慢查询
什么是MySQL慢查询呢?就是查询的SQL语句耗费较长时间。具体耗费多久算慢查询呢?这其实因业务而异,有些慢查询的阈值long_query_time是0.5s,有些的阈值可能是2s,即查询的时间超过这个阈值即视为慢查询。
慢查询的危害
- 用户体验差。
- 占用MySQL内存,影响性能。
- 并行查询增多,连接数耗尽。
- 造成业务变更DDL堵塞,备份失败等。
慢查询常见场景
在相同业务场景下,架构设计和库表索引设计会影响查询性能,良好的设计可以提高查询性能,反之会出现很多慢SQL。造成慢SQL的原因大概一下几大类:
SQL不合理
-
原因及现象
SQL异常的原因很多,例如库表结构设计不合理、索引缺失或没有利用好索引、扫描行数太多,单表数据量太大,使用了磁盘临时表,filesort查询等。
您可以在MySQL控制台的慢日志页面,查看执行缓慢的SQL,慢SQL的执行耗时,以及相关执行计划等信息,请参见查看慢日志。 -
解决方案
根据实际业务情况优化SQL,比如对查询进行优化,应尽量避免全表扫描,避免like '%abc%'模糊查询,避免在 where 子句中对字段进行表达式操作,尽量使用数字型字段等等。
实例到达瓶颈
-
原因及现象
实例到达瓶颈的原因一般有如下几种:- 业务量经过一段时间持续增长而没有扩容实例规格。
- 服务器的硬件老化,性能有损耗。
- 业务表数据量一直增加导致单表数据量太大,表数据结构也有变化,导致原来不慢的SQL变成慢SQL。
您可以在控制台的查看实例的资源使用情况。如果CPU,磁盘IO等资源使用率各项指标都接近100%,可能是实例到达了瓶颈。具体操作,请参见查看监控指标。
-
解决方案
确认是实例到达瓶颈后,建议升级实例规格。具体操作,请参见规格扩容。
内核版本升级
- 原因及现象
实例升级版本有可能会导致SQL执行计划发生改变,explain的执行计划中连接类型从好到坏的顺序是system>const>eq_ref>ref>fulltext>ref_or_null>index_merge>unique_subquery>index_subquery>range>index>all。如果SQL请求变慢,业务又不断重发请求,导致并行SQL查询比较多,会导致应用线程释放变慢,最终连接数耗尽,影响整个业务。更多执行计划信息,请参见MySQL官方文档。
您可以在控制台的查看实例的当前连接数指标。具体操作,请参见查看监控指标。 - 解决方案
请在控制台慢SQL监控中查看执行计划。根据执行计划分析索引使用情况、预估扫描的行数等,预估查询效率,重构SQL语句、调整索引,提升查询效率。
参数设置不当
- 原因及现象
部分SQL查询慢,可能是一些相关参数(如join_buffer_size,sort_buffer_size,tmp_table_size等)设置不当会导致性能变慢。
您可以在控制台查看实例的参数修改情况。具体操作,请参见修改参数组。 - 解决方案
调整全局相关参数,使其适合响应的业务场景或者业务SQL前设置会话级相关参数。具体请参见关系数据库MySQL版参数调优建议。
批量操作
-
原因及现象
如果有进行大批量的数据迁移导入、删除,以及查询等操作,会导致SQL执行变慢,磁盘IO使用率增大,磁盘使用量突增等。
您可以在控制台查看实例的磁盘总大小、磁盘使用量、IOPS等指标。具体操作,请参见查看监控指标。
-
解决方案
建议在业务低峰期执行大批量操作,或将大批量操作拆分后分批执行。
定时任务
-
原因及现象
如果实例负载监控数据随时间有规律性变化,可能是存在定时任务。
您可以在控制台查看实例监控DML相关的Delete语句、Update语句,Insert语句、Insert_Select语句、Replace语句、Replace_Select语句、Select语句等语句的执行频率等指标,判断是否有规律性变化。具体操作,请参见查看监控指标。
-
解决方案
调整定时任务的执行时间,建议在业务低峰期执行定时任务。