为什么mysql查询慢需要优化索引_mysql性能分析技巧

1次阅读

根本原因是索引未被使用,而非未建索引;常见失效场景包括where中使用函数、隐式类型转换、like左模糊;应通过explain分析type、key、extra字段,并遵循最左前缀原则合理建索引。

为什么mysql查询慢需要优化索引_mysql性能分析技巧

为什么 select 越查越慢,加了索引也没用?

根本原因往往不是没建索引,而是索引没被用上。mysql 优化器会根据统计信息、条件写法、数据分布等决定是否走索引——WHERE 中用了函数、隐式类型转换、或 LIKE 开头带通配符(如 '%abc'),都会让索引失效。

实操建议:

  • EXPLAINtype 字段:如果是 ALLindex,基本等于全表扫描
  • 检查 key 列是否为 NULL,是就说明没走索引
  • 留意 Extra 列:出现 using filesortUsing temporary 是性能红灯
  • 避免在索引列上做运算,比如 WHERE YEAR(create_time) = 2023 → 改成 WHERE create_time >= '2023-01-01' AND create_time

EXPLAIN 输出里哪些字段最关键?

EXPLAIN 不是看有没有“key”就完事,要盯住四个字段:typekeyrowsExtra

常见误判点:

  • typerange 看似还行,但如果 rows 显示 50 万,说明这个范围太大,实际效率接近全扫
  • key 显示用了索引,但 Extra 写着 Using index condition 是好事(ICP 下推),而 Using where 意味着回表后还要过滤,可能意味着索引覆盖不全
  • rows 是估算值,不准但有参考性;如果从几千突增到几十万,大概率是统计信息过期,可运行 ANALYZE table table_name 更新

联合索引怎么建才不白建?

联合索引不是字段砌,顺序决定生死。它本质是按最左前缀排序的 B+ 树,只支持“从左到右连续匹配”。

举个例子:索引是 (a, b, c),以下查询能用上:

  • WHERE a = 1 AND b = 2 ✅(用到前两列)
  • WHERE a = 1 AND b > 2 AND c = 3 ✅(b 范围查询后,c 无法再走索引,但该条件仍可用于过滤)
  • WHERE b = 2 AND c = 3 ❌(没用 a,跳过最左,整个索引失效)

建索引前先看慢查的 WHERE + ORDER BY + SELECT 字段组合,优先把高频过滤字段放左边,排序字段放中间,查询返回字段放右边(用于覆盖索引)。

什么时候该删索引而不是加索引?

索引不是越多越好。每个索引都增加写开销(INSERT/UPDATE/delete 都要维护)、占用磁盘、拖慢优化器决策速度。尤其当一个表有 10+ 索引却长期只有 1–2 个被用到,就是信号。

判断依据:

  • information_schema.statistics 或用 sys.schema_unused_indexes(MySQL 8.0+)找长期未命中的索引
  • 观察 Handler_read_* 状态变量,Handler_read_key 很低但 Handler_read_next 很高,说明索引没起到定位作用
  • 单表索引总数超过 5–6 个,且存在字段重复出现在多个索引中(如 (a)(a,b)(a,b,c)),优先保留最长的那个

真正难的不是建索引,是识别哪些查询本就不该走索引——比如日志类大表的分页查询 LIMIT 1000000, 20,再好的索引也救不了,得换方案(游标分页、延迟关联、或业务上限制深度)。

text=ZqhQzanResources