Files
leetcode-go/笔试/微派 Test1/03-单选题1-索引下推.md
T

90 lines
3.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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 | 索引下推在所有情况下都能提升查询性能 |
<details>
<summary>点击查看答案与解析</summary>
### ✅ 正确答案:**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] 一句话总结
> 索引下推的本质:把能尽早拒绝的行挡在门外,避免无效的回表开销。
</details>