索引下推:ICP优化
一、什么是索引下推(ICP) 1.1 问题场景 CREATE INDEX idx_a_b ON table(a, b); SELECT * FROM table WHERE a = 1 AND b LIKE '%abc%'; 传统执行(无ICP): 使用索引找到a=1的所有记录 回表获取完整数据 在Server层过滤b LIKE ‘%abc%’ 问题:大量无效回表。 1.2 ICP优化 ICP执行(MySQL 5.6+): 使用索引找到a=1的记录 在索引中直接过滤b LIKE ‘%abc%’ 只回表符合条件的记录 优势:减少回表次数。 二、ICP原理 2.1 传统流程 vs ICP流程 传统: 索引层:找到a=1的10条记录 ↓ 回表10次 存储引擎:获取10条完整数据 ↓ Server层:过滤b,最终2条符合 ICP: 索引层:找到a=1的10条记录 ↓ 在索引中过滤b 索引层:10条中2条符合b条件 ↓ 只回表2次 存储引擎:获取2条完整数据 2.2 关键 下推:将Server层的过滤条件下推到存储引擎层。 三、ICP的适用条件 3.1 启用条件 -- 查看ICP状态 SHOW VARIABLES LIKE 'optimizer_switch'; -- index_condition_pushdown=on -- 启用ICP SET optimizer_switch='index_condition_pushdown=on'; 3.2 使用场景 -- ✅ 可以使用ICP CREATE INDEX idx_a_b_c ON table(a, b, c); WHERE a = 1 AND b > 10 AND c = 3; -- a精确匹配 → 使用索引 -- b范围查询 → 使用索引 -- c过滤条件 → ICP下推到索引层 3.3 不适用场景 -- ❌ 主键索引(聚簇索引) -- 已经包含完整数据,无需下推 -- ❌ 覆盖索引 -- 不需要回表,无需下推 -- ❌ 全表扫描 -- 没有使用索引 四、EXPLAIN中的ICP 4.1 识别标志 EXPLAIN SELECT * FROM orders WHERE user_id = 123 AND status LIKE '%pending%'; 结果: ...