详解索引下推(ICP)(示例与解释)

索引下推(ICP)是一种数据库查询优化技术,通过在索引层应用过滤条件来减少数据扫描和IO,提高查询速度。文章通过一个订单表查询的例子,解释了不使用和使用ICP的区别,以及如何通过联合索引进一步优化。ICP是数据库优化器自动选择的策略,但并不适用于所有场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

0、前言

        许久不看索引下推ICP相关知识,有些模糊,在网上查了查后,发现很多相关文章直接摆上一堆图、讲的云里雾里的,因此这里做一下简明易懂的总结,全文无废话,方便复习。
        本文适合具有B+树、数据库索引等基础知识的同学阅读哈!


1、索引下推(ICP)是什么

1.1 概念

        ICP是一种数据库的查询优化技术,利用索引来提高查询性能:

  • 使用ICP前:在传统的查询流程中,数据库通常先读取满足条件的所有行,然后再通过排序、过滤等操作得到最终结果,这种方式的效率往往受限于内存和磁盘I/O速度等因素。
  • 使用ICP后:当查询涉及到多个表格时,索引下推将过滤条件尽可能转换成对应表格上的索引条件,从而尽可能减少需要扫描的表格数和读取的数据量,提高查询速度。

1.2 说人话

        使用ICP之前,对于单个非聚簇索引(二级索引)、并且存在范围条件筛选的情况下,需要先回表,把数据IO出来,然后再进行筛选。
        而使用索引下推后,是先筛选好满足条件的主键id,再去数据库进行IO。
        对比而言 ,显然后者IO的数据量更小,IO次数更少!——这就是ICP的意义。

2、举例说明ICP

2.1 举例

        只讲概念可能还是有些模糊,我们举出一个例子:

假设有一个订单表 order_table,其中包含以下字段:

  • order_id:订单ID,主键
  • user_id:用户ID
  • order_time:下单时间
  • order_status:订单状态

为了提高查询效率,我们可以在 user_idorder_time 字段上分别创建索引

 对于以上情况,我们执行以下SQL语句:

SELECT COUNT(*) FROM order_table WHERE user_id=123 AND order_time>='2023-01-01' AND order_time<='2023-01-31';

2.2 解释

        不使用索引下推,执行该语句需要扫描 user_id 索引来获取全部符合条件的订单,然后再对结果进行时间过滤匹配,由于表中数据量很大,会造成很大的IO开销

        使用索引下推,则可以先在索引层级上过滤出满足条件的索引行:user_id=123 是一个等值查询条件,可以在 user_id 索引层级上进行过滤;order_time>='2023-01-01'order_time<='2023-01-31' 则是时间范围条件,可以在 order_time 索引层级上进行过滤。
        MySQL会首先使用 user_id 索引查找符合条件的行,然后再使用 order_time 索引过滤出满足时间条件的索引行然后再到数据层级上获取订单数量,最后将减少了对磁盘的读取,从而提高了查询性能。

2.3 具体执行流程      

  1. 首先,MySQL会使用 user_id 索引来查找所有满足 user_id=123 的订单ID,并将这些ID保存下来。
  2. 然后,MySQL会使用 order_time 索引来查找所有满足 order_time>='2023-01-01' 和 order_time<='2023-01-31' 的订单ID,并将这些ID保存下来。
  3. 接着,MySQL会将这两个ID列表进行比较,只保留同时在这两个列表中出现的订单ID。
  4. 最后,MySQL会统计符合条件的订单数量,并返回结果。

3、关于索引下推的其他知识

        (1)索引下推是数据库优化器自动采取的策略
        (2)并非适合所有场景(效率问题)
        (3)对于以上第2节的例子,可以采用user_id 和 order_time作为联合索引,这样效率比索引下推会更高。

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

好奇的7号

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值