Index Condition Pushdown (ICP) 是 MySQL 5.6 引入的存儲引擎層優化:將部分 WHERE 條件「下推」到存儲引擎,利用索引列在引擎內部過濾,**減少回表次數與 Server-Engine 交互**。
| 階段 | 關閉 ICP | 開啟 ICP |
|---|---|---|
| 1 | 讀索引元組 → 回表讀全行 | 讀索引元組(**不回表**) |
| 2 | Server 層對全行做 WHERE 過濾 | 引擎層用索引列做 WHERE 過濾 |
| 3 | 符合條件才返回客戶端 | 符合條件才回表讀全行 → Server 層做剩餘過濾 |
-- 索引 idx_emp_fnln (first_name, last_name)
SELECT * FROM employees
WHERE first_name='Anneke' AND last_name LIKE '%sig';
最左前綴原則:first_name 可用索引,last_name LIKE '%sig' 無法用索引範圍掃描。
SET optimizer_switch='index_condition_pushdown=on';
-- 耗時 0.00060275s
-- Sending data: 0.000189s
-- EXPLAIN Extra: Using index condition
SET optimizer_switch='index_condition_pushdown=off';
-- 耗時 0.00097000s (慢 61%)
-- Sending data: 0.000735s (慢 3.9倍)
-- EXPLAIN Extra: Using where


first_name='Anneke' 讀 225 行 → 全部回表 → Server 層過濾 last_name LIKE '%sig' → 僅 1 行符合。**224 次無效回表**。last_name LIKE '%sig',**僅 1 行回表**。IO 與交互大幅下降。range/ref/eq_ref/ref_or_null 訪問類型Using where; Using index)-- 非覆蓋:觸發 ICP
EXPLAIN SELECT * FROM employees WHERE first_name='Anneke' AND last_name='Porenta';
-- Extra: Using index condition
-- 覆蓋索引:不觸發 ICP
EXPLAIN SELECT first_name,last_name FROM employees WHERE first_name='Anneke' AND last_name='Porenta';
-- Extra: Using where; Using index
optimizer_switch='index_condition_pushdown=on'(默認開啟)EXPLAIN 檢查 Using index condition 是否出現