深入浅出 MySQL慢查询定位与优化攻略

慢查询定位

开启慢查询

SHOW VARIABLES LIKE 'slow_query_log%'

SET global slow_query_log = ON;
SET global slow_query_log_file = 'h122-slow.log';
SET global log_queries_not_using_indexes = ON;
SET long_query_time = 10;

long_query_time

指定慢查询的阈值,单位是秒,默认值为10秒。

log_queries_not_using_indexes

控制是否记录未使用索引的查询语句。

查看慢日志

日志包含:

  • time:时间戳
  • User@Host:执行查询的用户和主机
  • Query_time:SQL语句执行的总耗时
  • Lock_time:等待表锁的时间
  • Rows_sent:返回记录行数
  • Rows_examined:扫描的记录总行数

mysqldumpslow

perl mysqldumpslow.pl -t 5 -s xxx-slow.log

慢查询优化

常见优化方案

只取需要的列与行

  • SELECT列表写全,不要SELECT *
  • 加好WHERE

为过滤与连接建索引

  • 优先给WHERE/JOIN/ORDER BY/GROUP BY中出现的列建索引

避免函数包裹列与隐式类型转换

模糊查询避免前导通配符

  • LIKE ‘%abc’无法用到普通B-Tree索引

分页优化(深分页杀手)

SELECT id, name FROM t
WHERE id > ?
ORDER BY id
LIMIT 20;

覆盖索引

  • 让查询只在索引层完成,避免回表

合理拆分OR/优先使用EXISTS

SELECT ... FROM t WHERE type=1 AND cond...
UNION ALL
SELECT ... FROM t WHERE type=2 AND cond...