--- tags: [笔试, 微派, MySQL, 索引, 数据库] create time: 2026-05-16 14:45 --- # 03 - 单选题 1:索引下推(Index Condition Pushdown) ## 题目 关于 MySQL InnoDB 存储引擎中的**索引下推(Index Condition Pushdown, ICP)**优化,以下说法**正确**的是: | 选项 | 内容 | |------|------| | A | 索引下推可以将条件判断从存储引擎层下推到 CPU 层执行 | | B | 索引下推适用于 ALL(全表扫描)类型的查询 | | C | 使用索引下推可以减少存储引擎访问表的次数(回表次数) | | D | 索引下推在所有情况下都能提升查询性能 |
点击查看答案与解析 ### ✅ 正确答案:**C** --- ### 详细解析 #### 什么是索引下推? 在优化器确定了访问数据的读策略(即选择了哪些索引)之后、读取数据之前,如果 WHERE 子句中还有可以利用索引中字段来评估的条件,则把这些条件的评估操作**下推给存储引擎层**执行,这个技术就叫索引下推。 #### 为什么需要索引下推?(问题背景) ```mermaid flowchart TD subgraph IC["无 ICP — 传统方式"] A[二级索引扫描到匹配的行] --> B["回表到聚簇索引获取完整行"] B --> C["在 Server 层检查剩余条件"] C --> D{"满足条件?"} D -->|"否"| E[丢弃该行] D -->|"是"| F["返回结果"] end subgraph IX["有 ICP — 优化后"] G[二级索引扫描到匹配的行] --> H["在索引层直接检查剩余条件"] H --> I{"满足条件?"} I -->|"否"| J["跳过回表"] I -->|"是"| K["回表到聚簇索引"] K --> L["Server 层再确认"] L --> M["返回结果"] end IC -.->|节省回表| IX ``` **没有 ICP 时**: 1. 二级索引只过滤第一个索引列(比如 `name = 'Alice'`) 2. **所有**匹配的行都要**回表**到聚簇索引取完整记录 3. Server 层再检查其他条件(如 `age > 25`) 4. 不满足条件的行被丢弃——但**回表已经发生了** **有了 ICP 后**: 1. 二级索引不仅过滤第一个列,还**在索引层尝试过滤其余条件** 2. 不满足索引列上的条件的行,**直接跳过回表** 3. 只有同时满足所有索引列条件的行才回表 #### 逐项分析 | 选项 | 正误 | 原因 | |------|------|------| | A | ❌ | 反了!ICP 是将条件从**Server 层**(CPU 层)下推到**存储引擎层**。应该是"上推"或题目说反了方向 | | B | ❌ | ICP 只在**使用二级索引**的查询中生效,ALL(全表扫描)不涉及索引,自然没有 ICP | | C | ✅ | **正确!**这是 ICP 的核心价值——减少不必要的回表操作 | | D | ❌ | ICP 需要索引中包含所有用到的列才能发挥效果,而且当回表后的额外过滤代价很低时,收益有限 | #### 适用场景 ```sql -- 复合索引 (name, age),ICP 可以发挥作用 SELECT * FROM users WHERE name LIKE 'A%' AND age > 25; -- 此时二级索引能过滤 name 和 age,减少回表 ``` > [!tip] 一句话总结 > 索引下推的本质:把能尽早拒绝的行挡在门外,避免无效的回表开销。