Index Condition Pushdown (ICP) 是 MySQL 5.6+ 引入的優化:將 WHERE 條件中**能用索引列計算的部分**下推到存儲引擎層,在讀取完整行之前先過濾,減少「回表」與「Server-Engine 交互」次數。本文結合官方 employees 測試庫,通過 EXPLAIN、SHOW PROFILES 實測量化效果,並梳理適用邊界。
WHERE 條件 → 不滿足則丟棄。
WHERE,將**僅涉及索引列的條件**打包下推。
employees(30 萬行)。employees:PK emp_no,二級索引 index_bh (birth_date, hire_date)。WHERE birth_date BETWEEN '1955-01-01' AND '1955-12-31' AND DATEDIFF(hire_date,birth_date)>12300 AND first_name LIKE 'S%b%'。| ICP 狀態 | Extra 輸出 | 說明 |
|---|---|---|
| OFF | Using where | 全回表後 Server 過濾 |
| ON | Using index condition; Using where | DATEDIFF(hire_date,birth_date)>12300 下推到存儲引擎過濾 |
SET profiling=1; -- ICP OFF SELECT * FROM employees WHERE birth_date BETWEEN '1955-01-01' AND '1955-12-31' AND DATEDIFF(hire_date,birth_date)>12300 AND first_name LIKE 'S%b%'; -- Duration: 0.123 s SET optimizer_switch='index_condition_pushdown=on'; -- ICP ON SELECT * FROM employees WHERE birth_date BETWEEN '1955-01-01' AND '1955-12-31' AND DATEDIFF(hire_date,birth_date)>12300 AND first_name LIKE 'S%b%'; -- Duration: 0.074 s
提速 ~40%,來源於:索引列條件下推後,存儲引擎直接過濾掉大量不滿足 DATEDIFF 的行,**避免了回表與 Server-Engine 交互**。
EXPLAIN 的 type 必須為 range、ref、eq_ref、ref_or_null,且**需要回表**(非覆蓋索引)。