当前位置: 首页 > news >正文

Mysql 索引下推(Index Condition Pushdown, ICP)详解

索引下推(Index Condition Pushdown, ICP)

什么是索引下推?

索引下推(ICP)是MySQL 5.6引入的一种优化技术,它允许在存储引擎层提前过滤数据,减少不必要的数据回表操作。

工作原理

对于辅助联合索引(name,age,position),传统查询流程(MySQL 5.6之前):

sqlSELECT * FROM employees WHERE name LIKE 'LiLei%' AND age = 22 AND position ='manager'
  1. 只能使用name字段索引(最左前缀原则)
  2. 在索引中找到所有name以’LiLei’开头的记录
  3. 对每条记录回表查询完整行数据
  4. 在服务器层过滤age和position条件

使用ICP优化后的流程:

  1. 在存储引擎层使用联合索引(name,age,position)
  2. 对name LIKE 'LiLei%'的记录,同时在索引层检查age和position条件
  3. 只对满足所有条件的记录回表查询

为什么范围查找没有使用ICP优化?

MySQL没有对范围查找使用ICP优化可能有以下原因:

  1. 结果集大小考虑:
    • LIKE 'KK%'通常能过滤出较小比例的数据(前缀匹配)
    • 范围查询(如>, <, BETWEEN)可能匹配大量数据,ICP效果不明显
  2. 实现复杂性:
    • 范围查询在索引中的排序特性与前缀匹配不同
    • 引擎需要更复杂的逻辑来处理范围条件的ICP
  3. 优化器决策:
    • MySQL优化器会基于统计信息评估ICP是否值得
    • 有时即使有范围条件,ICP仍可能被使用(取决于数据分布)

ICP的适用场景和限制

  1. 适用场景:
    • 辅助索引(二级索引)的查询
    • 查询条件包含索引列但无法完全用于索引查找
    • 特别是前缀匹配(LIKE 'KK%')非常适合ICP
  2. 限制:
    • 不适用于聚簇索引(主键索引),因为回表成本低
    • 不适用于覆盖索引(因为不需要回表)
    • 不是所有条件都能下推(如子查询、存储函数等)

如何验证 ICP 是否生效?

使用 EXPLAIN 查看执行计划,关注 Extra 列是否包含 Using index condition

EXPLAIN SELECT * FROM employees 
WHERE name LIKE 'LiLei%' AND age = 22 AND position = 'manager';

如果输出中包含 Using index condition,则说明 ICP 已生效。

总结

ICP通过将WHERE条件过滤下推到存储引擎,减少了不必要的回表操作,特别对前缀匹配等条件效果显著。范围查询未使用ICP主要是基于性能优化器的权衡,认为这种情况下ICP的收益可能不明显。

不同类型 SQL 语句中使用索引下推 ICP 的示例及解释:

概括

ICP 主要优化以下类型的查询:

  1. 联合索引 + 前缀匹配(LIKE 'xxx%')。
  2. 联合索引 + 范围查询(><BETWEEN) + 等值条件。
  3. 联合索引 + IN 列表或多列等值匹配。
  4. 联合索引 + 简单函数或空值检查。

1. 联合索引 + 前缀匹配(LIKE 'xxx%'

适用场景:联合索引的第一个字段使用前缀匹配,其他字段用于过滤。
示例

-- 假设有联合索引 (name, age, position)
SELECT * FROM employees 
WHERE name LIKE 'LiLei%' AND age = 22 AND position = 'manager';

ICP 优化

  • 传统方式:仅用 name LIKE 'LiLei%' 过滤索引,回表后再检查 ageposition
  • ICP 方式:在索引层同时检查 nameageposition,仅回表满足所有条件的记录。

2. 联合索引 + 范围查询(><BETWEEN

适用场景:联合索引的第一个字段是范围查询,其他字段用于过滤。
示例

-- 假设有联合索引 (age, salary, department)
SELECT * FROM employees 
WHERE age > 30 AND salary = 5000 AND department = 'IT';

ICP 优化

  • 传统方式:仅用 age > 30 过滤索引,回表后再检查 salarydepartment
  • ICP 方式:在索引层同时检查 agesalarydepartment,减少回表次数。

注意
虽然范围查询(如 age > 30)本身可能无法完全利用索引的有序性,但 ICP 仍可对后续等值条件(如 salary = 5000)进行过滤。

3. 联合索引 + IN 条件

适用场景:联合索引的第一个字段是 IN 列表,其他字段用于过滤。
示例

-- 假设有联合索引 (department, status, hire_date)
SELECT * FROM employees 
WHERE department IN ('IT', 'HR') AND status = 'active' AND hire_date > '2020-01-01';

ICP 优化

  • 传统方式:仅用 department IN ('IT', 'HR') 过滤索引,回表后再检查其他条件。
  • ICP 方式:在索引层同时检查 departmentstatushire_date,减少回表。

4. 联合索引 + 多列等值匹配

适用场景:联合索引的多个字段均为等值匹配。
示例

-- 假设有联合索引 (city, country, zip_code)
SELECT * FROM addresses 
WHERE city = 'Beijing' AND country = 'China' AND zip_code = '100000';

ICP 优化

  • 传统方式:使用 citycountry 过滤索引(最左前缀),回表后再检查 zip_code
  • ICP 方式:在索引层直接检查所有三个条件,无需回表不匹配的记录。

5. 联合索引 + 函数或表达式(部分支持)

适用场景:索引列上使用简单函数或表达式,且优化器能下推。
示例

-- 假设有联合索引 (UPPER(name), age)
SELECT * FROM employees 
WHERE UPPER(name) LIKE 'LILEI%' AND age = 22;

ICP 优化

  • 如果索引支持函数(如函数索引或虚拟列),ICP 可在索引层过滤 UPPER(name)age
  • 限制:复杂函数(如 SUBSTRINGDATE_FORMAT)可能无法下推。

6. 联合索引 + IS NULLIS NOT NULL

适用场景:联合索引的字段包含空值检查。
示例

-- 假设有联合索引 (email, phone, status)
SELECT * FROM users 
WHERE email IS NOT NULL AND phone = '123456789' AND status = 'active';

ICP 优化

  • 在索引层过滤 email IS NOT NULLphonestatus,减少回表。

7. 联合索引 + 混合条件(范围 + 等值)

适用场景:联合索引的字段混合使用范围和等值条件。
示例

-- 假设有联合索引 (join_date, salary, department)
SELECT * FROM employees 
WHERE join_date BETWEEN '2020-01-01' AND '2023-01-01' AND salary = 8000 AND department = 'Engineering';

ICP 优化

  • 在索引层过滤 join_date 范围、salarydepartment,减少回表。
http://www.dtcms.com/a/297543.html

相关文章:

  • RK3588 HDMI-RX 驱动、RGA 加速与 OpenCV GStreamer 支持完整指南
  • 测试覆盖率:衡量测试的充分性和完整性
  • 巧用Proxy与异步编程:绕过浏览器安全限制实现文件选择器触发
  • JAVA同城服务家政服务家政派单系统源码微信小程序+微信公众号+APP+H5
  • 大语言模型生成式人工智能企业应用
  • 【Android】桌面小组件开发
  • 【通识】如何看电路图
  • Python 程序设计讲义(21):循环结构——while循环
  • C++ 常用的数据结构(适配器容量:栈、队列、优先队列)
  • centos 7 开启80,443端口,怎么弄?
  • CentOS 8 安装HGDB V4.5 psql命令执行报错
  • VR 污水处理技术赋能广州猎德污水处理厂,处理效率显著提升
  • 从0开始学习R语言--Day57--SCAD模型
  • 无需 Root 关闭联网验证 随意修改手机名称(适用于OPPO、一加、真我)
  • 图论水题日记
  • 图论:最小生成树
  • 从零开始:在 PyCharm 中搭建 Django 商城的用户注册与登录功能(轮播图+商品页-小白入门版)
  • 判断子序列-leetcode
  • HAL 中断
  • Python 数据分析(一):NumPy 基础知识
  • Kubernetes资源优化完整指南:从理论到实践的全面解决方案
  • Python之JSON:数据交换的轻量级桥梁
  • 【Unity笔记】OpenXR 之VR串流开发笔记:通过RenderTexture实现仅在PC端展示UI,在VR眼镜端隐藏UI
  • C语言|指针的应用
  • 算法:最长递增子序列解法记录
  • 【RDMA】Adapters PRM Mellanox Adapters Programmer’s Reference mellanox网卡编程手册0.52
  • C 语言输入输出 (I/O)
  • 数据结构学习之堆
  • 【C语言进阶】一篇文章教会你文件的读写
  • 基于GeoTools和SpringBoot的省域驾车最快路线生成实践