90 lines
3.2 KiB
Markdown
90 lines
3.2 KiB
Markdown
|
|
---
|
|||
|
|
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>
|