如何通过MySQL执行计划Extra列的Using Index判断索引使用效率?

2026-05-07 12:201阅读0评论SEO基础
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计950个文字,预计阅读时间需要4分钟。

如何通过MySQL执行计划Extra列的Using Index判断索引使用效率?

Extra 列表中出现 Using index 是好事,但不等于没有索引问题——它只说明使用了覆盖索引,不代表查询设计合理、索引结构最优,更不意味着没有冗余字段或顺序缺失。

怎么一眼看出 Using index 是真覆盖还是假高效

覆盖索引的本质是:查询中 SELECT 的所有列 + WHERE 用到的所有列,全部落在同一个索引的最左前缀范围内。

常见误判点:

  • Using index,但 WHERE 条件用了函数(如 WHERE YEAR(hire_time) = 2023)→ 实际走不了索引范围扫描,type 可能是 indexALL,性能仍差
  • 索引是 (name, age, position),但查询写成 SELECT * FROM employees WHERE age = 25 → 不满足最左前缀,Extra 不会显示 Using index,哪怕 age 在索引里
  • SELECT 中包含 TEXTBLOB 字段 → 即使其他字段被索引覆盖,InnoDB 也无法把大字段存进二级索引页,Using index 不会出现

Using indexUsing where; Using index 的关键区别在哪

两者都表示走了覆盖索引,但过滤动作发生的层级不同,直接影响扫描行数和响应稳定性:

  • Using index:整个 WHERE 条件都能用索引精确匹配或范围扫描(比如 WHERE name = 'Alice' AND age BETWEEN 20 AND 30),引擎层直接筛完,不回表也不在 server 层再过滤
  • Using where; Using index:索引覆盖了所有字段,但 WHERE 中有无法下推到引擎层的条件,例如 LIKE '%suffix'IS NULL、或者涉及隐式类型转换(如字符串字段查 WHERE status = 1)→ 这些条件必须由 server 层对引擎返回的每一行再做一次判断
  • 实际影响:Using where; Using indexrows 值往往偏高,因为引擎返回了更多中间结果;而 filtered 列如果远低于 100,就是 server 层过滤掉大量数据的信号

为什么有时加了索引却看不到 Using index

不是索引没生效,而是“覆盖”这个前提没达成。几个高频漏点:

  • SELECT *:除非是聚簇索引(主键索引)本身,否则二级索引不可能覆盖所有列,Extra 一定不会是 Using index
  • 查询中用了 DISTINCTGROUP BYORDER BY 非索引字段 → 即使 SELECT 字段全在索引里,也可能触发 Using temporaryUsing filesort,挤掉 Using index
  • 索引字段含 NULL 且查询条件为 IS NOT NULL:InnoDB 对 NULL 的处理会让部分优化失效,Extra 可能退化为 Using where
  • MySQL 版本低于 5.6:不支持 Index Condition Pushdown,某些本该下推的条件被迫留在 server 层,导致 Using where; Using index 出现频率更高,甚至误判为“没走索引”

真正要盯的不是有没有 Using index,而是它出现时对应的 key_len 是否合理、rows 是否随数据增长线性上升、以及 filtered 是否稳定在 80 以上。这些比单看 Extra 更早暴露索引设计隐患。

标签:Mysql

本文共计950个文字,预计阅读时间需要4分钟。

如何通过MySQL执行计划Extra列的Using Index判断索引使用效率?

Extra 列表中出现 Using index 是好事,但不等于没有索引问题——它只说明使用了覆盖索引,不代表查询设计合理、索引结构最优,更不意味着没有冗余字段或顺序缺失。

怎么一眼看出 Using index 是真覆盖还是假高效

覆盖索引的本质是:查询中 SELECT 的所有列 + WHERE 用到的所有列,全部落在同一个索引的最左前缀范围内。

常见误判点:

  • Using index,但 WHERE 条件用了函数(如 WHERE YEAR(hire_time) = 2023)→ 实际走不了索引范围扫描,type 可能是 indexALL,性能仍差
  • 索引是 (name, age, position),但查询写成 SELECT * FROM employees WHERE age = 25 → 不满足最左前缀,Extra 不会显示 Using index,哪怕 age 在索引里
  • SELECT 中包含 TEXTBLOB 字段 → 即使其他字段被索引覆盖,InnoDB 也无法把大字段存进二级索引页,Using index 不会出现

Using indexUsing where; Using index 的关键区别在哪

两者都表示走了覆盖索引,但过滤动作发生的层级不同,直接影响扫描行数和响应稳定性:

  • Using index:整个 WHERE 条件都能用索引精确匹配或范围扫描(比如 WHERE name = 'Alice' AND age BETWEEN 20 AND 30),引擎层直接筛完,不回表也不在 server 层再过滤
  • Using where; Using index:索引覆盖了所有字段,但 WHERE 中有无法下推到引擎层的条件,例如 LIKE '%suffix'IS NULL、或者涉及隐式类型转换(如字符串字段查 WHERE status = 1)→ 这些条件必须由 server 层对引擎返回的每一行再做一次判断
  • 实际影响:Using where; Using indexrows 值往往偏高,因为引擎返回了更多中间结果;而 filtered 列如果远低于 100,就是 server 层过滤掉大量数据的信号

为什么有时加了索引却看不到 Using index

不是索引没生效,而是“覆盖”这个前提没达成。几个高频漏点:

  • SELECT *:除非是聚簇索引(主键索引)本身,否则二级索引不可能覆盖所有列,Extra 一定不会是 Using index
  • 查询中用了 DISTINCTGROUP BYORDER BY 非索引字段 → 即使 SELECT 字段全在索引里,也可能触发 Using temporaryUsing filesort,挤掉 Using index
  • 索引字段含 NULL 且查询条件为 IS NOT NULL:InnoDB 对 NULL 的处理会让部分优化失效,Extra 可能退化为 Using where
  • MySQL 版本低于 5.6:不支持 Index Condition Pushdown,某些本该下推的条件被迫留在 server 层,导致 Using where; Using index 出现频率更高,甚至误判为“没走索引”

真正要盯的不是有没有 Using index,而是它出现时对应的 key_len 是否合理、rows 是否随数据增长线性上升、以及 filtered 是否稳定在 80 以上。这些比单看 Extra 更早暴露索引设计隐患。

标签:Mysql