using index表示索引覆盖、无需回表;即select和where涉及的所有字段均被同一索引最左前缀完全覆盖,mysql仅通过索引叶子节点即可返回全部数据,i/o开销最小。

Using index 表示索引覆盖,不用回表
它说明 MySQL 仅靠索引的叶子节点就拿到了 SELECT 和 WHERE 所需的全部字段,连主键聚簇索引(即真实数据行)都不用访问。这是“索引覆盖”的明确信号,I/O 开销最小。
关键前提有三个:
-
SELECT的所有列 +WHERE中用到的所有列,必须全部落在同一个索引里 - 顺序要满足最左前缀原则:不能跳过前导列(比如索引是
(a, b, c),但查询只用了b = 1,就不成立) - 不能对索引列做函数操作或隐式转换(如
WHERE YEAR(create_time) = 2023或status = 1但status是VARCHAR)
Using index 和 Using where; Using index 容易混淆
两者都表示“索引覆盖”,但过滤动作发生的层级不同,直接影响性能稳定性:
-
Using index:整个WHERE条件都能被索引精确匹配或范围扫描(如name = 'Alice' AND age BETWEEN 20 AND 30),过滤完全在存储引擎层完成,Server 层不参与 -
Using where; Using index:索引确实覆盖了所有字段,但部分条件无法下推(比如LIKE '%suffix'、IS NULL、隐式类型转换),引擎先返回一批索引项,再由 Server 层逐行过滤
后者的 rows 值通常偏高,filtered 列如果远低于 100%,就是 Server 层丢弃大量中间结果的明确提示。
Using index condition 不等于 Using index
Using index condition 出现在二级索引扫描中,表示启用了 ICP(索引条件下推)——部分 WHERE 条件被下推到 InnoDB 层,在遍历索引时就做过滤,减少回表量。
- 它只出现在
type是ref或range、且key显示用了联合索引的场景 -
key_len不会因下推而变长,仍只反映最左匹配长度 - 主键/聚簇索引上永远不会出现这个提示(叶子节点就是整行,下推无意义)
- 不可下推的条件包括:函数调用(
UPPER(c))、表达式(c + 1 > 10)、子查询、非索引列模糊匹配(address LIKE '%北京%')
看到 Using index 就代表没问题?未必
它只是说明当前查询“走通了覆盖路径”,不代表索引设计合理或查询高效:
- 有
Using index,但WHERE用了LIKE '%abc'→ 实际是全索引扫描(type: index),性能仍差 - 索引包含冗余字段(比如
(a, b, c, d),但查询只查a, b),浪费空间且拖慢写入 -
SELECT *包含TEXT或BLOB字段 → InnoDB 不会把大字段存进二级索引页,Using index不会出现 - 复合索引顺序不合理(比如高频查询是
WHERE b = ? AND c = ?,但索引建成了(a, b, c))→ 前导列a总是空值或常量才可能触发覆盖
真正要盯住的,不是 Extra 是否好看,而是 rows 是否可控、filtered 是否接近 100%、以及这个索引是否被其他更频繁的查询复用。











