using where 表示mysql server层需对存储引擎返回的行进行额外过滤,常见于查询字段不在索引中、where条件含函数或隐式转换、复合索引未满足最左匹配、或部分条件无法下推至引擎等情况。

Using where 表示 MySQL Server 层需要对存储引擎返回的行做额外过滤,不是所有 WHERE 条件都在索引层完成匹配。
Using where 出现在什么场景下
它和“是否用索引”没有直接因果关系,而是反映 Server 层是否介入了行级过滤。常见于以下几种情况:
- 查询字段不在索引中(例如
SELECT name FROM user WHERE age = 25,只有age索引,但name需回表取) - WHERE 中部分条件无法下推到存储引擎(如函数、类型隐式转换、
OR混合索引列与非索引列) - 使用了覆盖索引,但 WHERE 里还有索引未包含的字段(比如复合索引
(a,b),查询WHERE a=1 AND c='x',c不在索引中) - 索引能定位范围,但最终筛选仍需 Server 层判断(如
WHERE a > 10 AND b LIKE '%test%',b是非前缀模糊,无法走索引)
Using where 和 Using index condition 的关键区别
两者都涉及 Server 层参与,但发生位置和代价不同:
-
Using index condition:发生在存储引擎层(如 InnoDB),引擎拿到索引后,先用部分 WHERE 条件(可下推的)在索引页内做过滤,再回表或读取数据 —— 这叫 Index Condition Pushdown(ICP),MySQL 5.6+ 默认开启 -
Using where:引擎返回一批行(可能已按索引扫描),Server 层再逐行应用剩余 WHERE 条件做判断 —— 多一次拷贝 + 遍历,IO 和 CPU 开销更高 - 典型共存现象:
Using where; Using index表示用了覆盖索引(无需回表),但仍有 Server 层过滤;而Using index condition通常不带Using where,因为过滤已提前在引擎内完成
为什么 type=ALL 却还显示 Using where
这是最容易误解的一点:type=ALL 表示全表扫描,不代表没走任何索引逻辑;Extra 中的 Using where 依然有效,含义不变 —— 它只是说明 Server 层仍在过滤。
- 例如
EXPLAIN SELECT * FROM rental WHERE customer_id >= 373显示type=ALL+Using where:优化器判断该范围选择率太高(比如占表 80% 行),走索引再回表反而更慢,于是放弃索引,直接全扫,但 WHERE 条件仍由 Server 层执行 - 换句话说:
type描述“怎么取数据”,Extra描述“取完后怎么筛”,二者独立 - 验证方式:关掉 ICP(
SET optimizer_switch='index_condition_pushdown=off'),再看执行计划,常会发现原本的Using index condition变成Using where
真正要注意的是那些看似走了索引(type=range/ref)、却仍带 Using where 的查询 —— 它暴露了条件未被完全下推,往往是隐式转换、函数包裹或索引设计断层导致的。这类问题在高并发下容易放大延迟。











