团队里的慢查询,十有八九不是 SQL 写得烂,而是索引从一开始就没设计对。下面七条,是我从两年的慢查询日志里总结出的军规。
军规清单
- 为查询建索引,不为表建索引。 没有查询场景的索引是纯粹的负债。
- 遵守最左前缀。
(a, b, c)的联合索引救不了只按c过滤的查询。 - 能用覆盖索引就别回表。
SELECT的列都在索引里,查询就不用碰主键树。 - 高区分度的列放前面。 性别这种低基数列,单独建索引基本是浪费。
- 不要在索引列上做运算。
WHERE DATE(create_time) = '...'等于亲手废掉索引。 - 字符串前缀索引要想清楚长度。 太短不区分,太长浪费页空间。
- 索引不是免费的。 每个索引都在拖慢写入,并占用 buffer pool。
一条慢 SQL 的解剖
-- 优化前:全表扫描,2.3s
SELECT * FROM orders
WHERE status = 'PAID' ORDER BY create_time DESC LIMIT 20;
-- 建 (status, create_time) 联合索引后:4ms
军规之外只有一句话:上线前 EXPLAIN 一遍,胜过上线后排查一周。