MySQL索引下推index condition pushdown

 更新时间:2024年08月05日 10:20:47   作者:zxrhhm  
索引下推是MySQL 5.6版本引入的一种数据库查询优化技术,本文主要介绍了MySQL索引下推index condition pushdown,具有一定的参考价值,感兴趣的可以了解一下

索引下推(Index Condition Pushdown,简称ICP)是MySQL 5.6版本引入的一种数据库查询优化技术。ICP的主要目的是通过利用数据库引擎中的索引和过滤条件,将部分过滤工作下推到存储引擎层面进行处理,从而减少不必要的数据读取和传输,提升查询性能和整体系统效率。

索引下推的工作原理

在传统的查询执行过程中,数据库引擎首先根据索引定位到符合过滤条件的数据行,并将这些数据行读取到内存中,然后再进一步进行过滤操作。而索引下推则在这一步骤中尽可能地将过滤操作下推到存储引擎层面,避免将不符合条件的数据行读取到内存中。具体实现方式可以是通过存储引擎提供的接口或者钩子函数,让存储引擎在读取索引页时就进行额外的过滤操作。

索引下推的优势

  • 减少数据读取和传输:通过索引下推,可以在存储引擎层面就过滤掉不符合条件的数据,减少了需要传递给查询引擎的数据量和内存消耗。
  • 降低磁盘I/O:由于减少了不必要的数据读取,因此也降低了磁盘I/O的次数,这对于提升查询性能尤为重要。
  • 提高查询效率:在复杂查询条件、多列条件的查询中,索引下推能够更有效地减少不必要的数据读取和传输,从而提高查询效率。

索引下推的应用场景

  • 索引下推并不是对所有类型的查询都适用,它更适用于那些包含复杂查询条件、多列条件的查询场景。在这些场景中,索引下推能够显著减少查询过程中的数据读取和传输量,从而提升查询性能。

索引下推与回表查询

  • 在联合索引的场景中,索引下推还可以减少回表查询的次数。例如,当为age和name字段创建了联合索引,并执行查询语句SELECT * FROM EMPLOYEES WHERE first_name LIKE ‘James’ AND last_name = ‘Landry’;时,如果没有使用索引下推,MySQL会根据联合索引查询first_name 字段等于"James"的数据,然后进行回表查询以获取完整的数据行。而使用索引下推后,MySQL会在存储引擎层面就进一步判断last_name 是否等于Landry,只有同时满足这两个条件的数据行才会被读取并返回给查询引擎,从而减少了回表查询的次数。

索引下推的启用与关闭

select @@optimizer_switch  -- 默认是打开的 

-- 关闭ICP
set optimizer_switch = 'index_condition_pushdown=off';

-- 打开ICP
set optimizer_switch = 'index_condition_pushdown=on';

set profiling=1

-- 使用索引下推
SELECT * FROM EMPLOYEES WHERE first_name LIKE 'James' AND last_name = 'Landry';

(root@localhost) 09:12:52 [test1]> SELECT * FROM EMPLOYEES WHERE first_name LIKE 'James' AND last_name = 'Landry';
+-------------+------------+-----------+---------+---------------+------------+----------+---------+----------------+------------+---------------+
| EMPLOYEE_ID | FIRST_NAME | LAST_NAME | EMAIL   | PHONE_decimal | HIRE_DATE  | JOB_ID   | SALARY  | COMMISSION_PCT | MANAGER_ID | DEPARTMENT_ID |
+-------------+------------+-----------+---------+---------------+------------+----------+---------+----------------+------------+---------------+
|         127 | James      | Landry    | JLANDRY | 650.124.1334  | 2007-01-14 | ST_CLERK | 2400.00 |           NULL |        120 |            50 |
+-------------+------------+-----------+---------+---------------+------------+----------+---------+----------------+------------+---------------+
1 row in set (0.00 sec)

(root@localhost) 09:08:52 [test1]> explain SELECT * FROM EMPLOYEES WHERE first_name LIKE 'James' AND last_name = 'Landry';
+----+-------------+-----------+------------+-------+---------------+-------------+---------+------+------+----------+-----------------------+
| id | select_type | table     | partitions | type  | possible_keys | key         | key_len | ref  | rows | filtered | Extra                 |
+----+-------------+-----------+------------+-------+---------------+-------------+---------+------+------+----------+-----------------------+
|  1 | SIMPLE      | EMPLOYEES | NULL       | range | EMP_NAME_IX   | EMP_NAME_IX | 140     | NULL |    1 |   100.00 | Using index condition |
+----+-------------+-----------+------------+-------+---------------+-------------+---------+------+------+----------+-----------------------+
1 row in set, 1 warning (0.01 sec)

show profiles;

show profile for query 1;

show profile for query 2;

禁用 索引下推,观察执行计划

禁用 Index Condition Pushdown(ICP) 索引下推

(root@localhost) 09:22:32 [test1]> explain SELECT /*+ no_ipc () */ * FROM EMPLOYEES WHERE first_name LIKE 'James' AND last_name = 'Landry';
+----+-------------+-----------+------------+-------+---------------+-------------+---------+------+------+----------+-------------+
| id | select_type | table     | partitions | type  | possible_keys | key         | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-----------+------------+-------+---------------+-------------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | EMPLOYEES | NULL       | range | EMP_NAME_IX   | EMP_NAME_IX | 140     | NULL |    1 |   100.00 | Using where |
+----+-------------+-----------+------------+-------+---------------+-------------+---------+------+------+----------+-------------+
1 row in set, 2 warnings (0.00 sec)

(root@localhost) 09:22:46 [test1]> explain SELECT * FROM EMPLOYEES WHERE first_name LIKE 'James' AND last_name = 'Landry';
+----+-------------+-----------+------------+-------+---------------+-------------+---------+------+------+----------+-------------+
| id | select_type | table     | partitions | type  | possible_keys | key         | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-----------+------------+-------+---------------+-------------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | EMPLOYEES | NULL       | range | EMP_NAME_IX   | EMP_NAME_IX | 140     | NULL |    1 |   100.00 | Using where |
+----+-------------+-----------+------------+-------+---------------+-------------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

总结

索引下推是MySQL 5.6及以上版本提供的一种查询优化技术,它通过将部分过滤工作下推到存储引擎层面进行处理,减少了不必要的数据读取和传输,降低了磁盘I/O次数,提高了查询性能和整体系统效率。在复杂查询条件、多列条件的查询场景中,索引下推能够发挥更大的作用。

到此这篇关于MySQL索引下推index condition pushdown的文章就介绍到这了,更多相关MySQL索引下推内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • mysql 获取当前日期函数及时间格式化参数详解

    mysql 获取当前日期函数及时间格式化参数详解

    这篇文章主要介绍了mysql 获取当前日期函数now()及时间格式化DATE_FROMAT函数以及参数详细介绍,需要的朋友可以参考下
    2014-08-08
  • 解决MySQL Sending data导致查询很慢问题的方法与思路

    解决MySQL Sending data导致查询很慢问题的方法与思路

    这篇文章主要介绍了解决MySQL Sending data导致查询很慢问题的方法与思路,感兴趣的小伙伴们可以参考一下
    2016-04-04
  • mysql函数全面总结

    mysql函数全面总结

    这篇文章主要介绍了mysql函数,下面文章从MySQL常用的函数开始介绍、还有数值函数,利用举例说明的形式展开内容,需要的朋友可以参考一下
    2021-11-11
  • delete in子查询不走索引问题分析

    delete in子查询不走索引问题分析

    这篇文章主要为大家介绍了delete in子查询不走索引的问题分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • 深入理解Mysql的四种隔离级别

    深入理解Mysql的四种隔离级别

    开发工作中我们会使用到事务,那你们知道事务又分哪几种吗?MYSQL标准定义了4类隔离级别,用来限定事务内外的哪些改变是可见的,哪些是不可见的。低的隔离级一般支持更高的并发处理,并拥有更低的系统开销。下面通过这篇文章我们来一起深入理解Mysql中的四种隔离级别。
    2016-11-11
  • Mysql分组查询取最新的几种方案总结

    Mysql分组查询取最新的几种方案总结

    在写报表功能时遇到一个需要根据用户id分组查询最新一条钱包明细数据的需求,下面这篇文章主要给大家总结介绍了关于Mysql分组查询取最新的几种方案,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-05-05
  • MySQL中int(n)后面的n到底代表的是什么意思

    MySQL中int(n)后面的n到底代表的是什么意思

    这篇文章主要介绍了MySQL中int(n)后面的n到底代表的是什么意思 ,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • 详解MySQL的Seconds_Behind_Master

    详解MySQL的Seconds_Behind_Master

    对于mysql主备实例,seconds_behind_master是衡量master与slave之间延时的一个重要参数。通过在slave上执行"show slave status;"可以获取seconds_behind_master的值。
    2021-05-05
  • mysql间隙锁的具体使用

    mysql间隙锁的具体使用

    MySQL中有多种锁类型,本文主要介绍了mysql间隙锁的具体使用,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧
    2024-02-02
  • MySql索引原理和SQL优化方式

    MySql索引原理和SQL优化方式

    索引是提升数据库查询效率的有序存储结构,包括主键索引、唯一索引、普通索引等,约束则用于数据完整性,包含主键、唯一、外键等约束,B+树是常用的索引结构,减少磁盘IO次数,索引应用场景包括where、groupby、orderby
    2024-09-09

最新评论