定义
慢SQL指的是执行时间较长,影响数据库性能的SQL语句。在MySQL中,通常认为执行时间超过1秒(或自定义阈值)的查询可以被视为慢查询。这类SQL语句可能会导致数据库响应缓慢、资源占用过高等问题,严重时甚至会拖垮整个数据库服务。
通常慢SQL统计的时间为:锁等待时间、I/O等待时间、CPU计算时间、内存访问时间等所有在数据库服务器内部发生的操作时间。
但一般不包括:客户端与服务器之间的网络传输时间。即数据从MySQL服务器发送结果集到客户端所花费的时间,并不会被计算在慢查询的日志记录时间内。
提取
-
启动慢查询日志
设置配置文件
my.cnf[mysqld] slow_query_log=1 long_query_time=10 -
分析日志,提取耗时的查询
可以使用mysqldumpslow来分析日志 或者 人工审查日志,来获取慢SQL
处理
从业务角度
如果慢SQL本身是简单查询,但扫描返回的数据本身是十几万或者上百万行,这个是符合预期的,需要从业务上判断是否真的需要返回那么多条数据;或者考虑分页展示(也要避免深分页)。
从系统角度
- 观察执行SQL时,系统资源(CPU、内存等)是否存在耗尽的问题。如果存在资源耗尽的情况,出现慢SQL即为正常现象,需要考虑是否扩容服务器,或者对一些高资源消耗的应用进行优化。不过,慢SQL日志无法记录由于网络波动而导致的“慢SQL”,如果要检测这一点,需要在代码中手动计算
查询资源消耗
- top 查询资源占用(P 按CPU排序,M 按Mem排序)
- top -H -p {pid} # -H 为线程模式,-p 为指定pid
- jstack -l {pid} > output.txt
- cat output.txt | grep -i {Ootid}
从数据库角度
- EXPLAIN 分析SQL
对于从日志中提取出来的慢查询,使用EXPLAIN关键字来查看MySQL是如何执行这些查询的。通过EXPLAIN输出的信息,可以了解到MySQL为执行查询选择了哪些索引、是否进行了全表扫描、连接顺序等重要细节。,是否走了索引(type=ref/range/index),是否有全表扫描(type=ALL)+----+-------------+----------+------------+-------+---------------+---------+---------+-----+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+----------+------------+-------+---------------+---------+---------+-----+------+----------+-------------+ | 1 | SIMPLE | lineitem | NULL | index | NULL | PRIMARY | 8 | NULL | 1 | 100 | Using index | +----+-------------+----------+------------+-------+---------------+---------+---------+-----+------+----------+-------------+ - 合理添加索引:在频繁查询的列(如主键、外键、条件列)上建立索引。
- 避免重复索引:例如对 (a, b) 和 (a) 同时建索引是多余的。避免过度索引:每个索引都会影响写入性能(INSERT/UPDATE/DELETE)。
- 复合索引最左匹配原则:联合索引 (col1, col2, col3) 可以命中 col1, col1+col2,但不能命中 col2 或 col3。
- 覆盖索引:如果查询字段都在索引中,则不需要回表,效率更高。
- 避免
SELECT *,只查询需要的字段。 - 减少子查询嵌套,改用 JOIN 操作。
- 控制分页深度,避免 LIMIT offset, size 中 offset 过大(先使用WHERE过滤)。
- 避免在 WHERE 条件中对字段进行函数操作,会导致索引失效。
SHOW ENGINE INNODB STATUS;查看是否存在锁等待、死锁等问题:- 避免长事务,减少行锁持有时间。
- 使用合适的事务隔离级别,降低锁竞争。
总结对比
| 维度 | 关键点 |
|---|---|
| 业务角度 | 判断是否真的需要返回大量数据;分页展示或异步导出 |
| 系统角度 | 监控服务器资源,排查高负载、线程阻塞、网络延迟等问题 |
| 数据库角度 | 优化执行计划、索引、SQL语句、表结构、锁机制等 |