团队里的慢查询,十有八九不是 SQL 写得烂,而是索引从一开始就没设计对。下面七条,是我从两年的慢查询日志里总结出的军规。

军规清单

  1. 为查询建索引,不为表建索引。 没有查询场景的索引是纯粹的负债。
  2. 遵守最左前缀。 (a, b, c) 的联合索引救不了只按 c 过滤的查询。
  3. 能用覆盖索引就别回表。 SELECT 的列都在索引里,查询就不用碰主键树。
  4. 高区分度的列放前面。 性别这种低基数列,单独建索引基本是浪费。
  5. 不要在索引列上做运算。 WHERE DATE(create_time) = '...' 等于亲手废掉索引。
  6. 字符串前缀索引要想清楚长度。 太短不区分,太长浪费页空间。
  7. 索引不是免费的。 每个索引都在拖慢写入,并占用 buffer pool。

一条慢 SQL 的解剖

-- 优化前:全表扫描,2.3s
SELECT * FROM orders
WHERE status = 'PAID' ORDER BY create_time DESC LIMIT 20;

-- 建 (status, create_time) 联合索引后:4ms

军规之外只有一句话:上线前 EXPLAIN 一遍,胜过上线后排查一周。