0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

MySQL索引下推知识分享

OSC开源社区 来源:OSCHINA 社区 2022-12-27 09:49 次阅读

作者 | 京东云开发者-刘邓忠

Mysql 是大家最常用的数据库,下面为大家带来 mysql 索引下推知识点的分享,以便巩固 mysql 基础知识,如有错误,还请各位大佬们指正。

1 什么是索引下推

索引下推 (Index Condition Pushdown,索引条件下推,简称 ICP),是 MySQL5.6 版本的新特性,它可以在对联合索引遍历过程中,对索引中包含的所有字段先做判断,过滤掉不符合条件的记录之后再回表,能有效的减少回表次数(目前我们使用的 mysql 版本较高,一般大家可能感觉这是正常的,但是 mysql5.6 之前都不是这样实现的,下面会细细道来)。

1.1 适用条件

我们先来了解一下索引下推的使用条件及限制:

只支持 select。

当需要访问全表时,ICP 用于 range,ref,eq_ref 和 ref_or_null 访问类型。

ICP 可用于 InnoDB 和 MyISAM 表,包括分区的 InnoDB 和 MyISAM 表。(5.6 版本不适用分区表查询,5.7 版本后可以用于分区表查询)。

对于 InnDB 引擎只适用于二级索引(也叫辅助索引),因为 InnDB 的聚簇索引会将整行数据读到 InnDB 的缓冲区,这样一来索引条件下推的主要目的减少 IO 次数就失去了意义。因为数据已经在内存中了,不再需要去读取了。

在虚拟生成列上创建的辅助索引不支持 ICP(注:InnoDB 支持虚拟生成列的辅助索引)。

使用了子查询的条件无法下推。

使用存储过程或函数的条件无法下推(因为因为存储引擎没有调用存储过程或函数的能力)。

触发条件无法下推。(有关触发条件的信息,请参阅官方资料:Section 8.2.2.3, “Optimizing Subqueries with the EXISTS Strategy”.。)

1.2 原理介绍

首先,我们大致回顾下 mysql 的基本架构:

374cf660-852e-11ed-bfe3-dac502259ad0.png

MySQL 基本的架构示例图 MySQL 服务层主要负责 SQL 语法解析、生成执行计划等,并调用存储引擎层去执行数据的存储和查询。

索引下推的下推其含义就是指将部分上层(服务层)负责的事情,交给了下层(引擎层)去处理。

在 MySql 5.6 版本之前没有索引下推这个功能,从 5.6 版本后才加上了这个优化项。我们先简单对比一下使用和未使用 ICP 两种情况下,MySql 的查询过程吧。

1) 未使用 ICP 的情况下:

- 存储引擎读取索引记录;

- 根据索引中的主键值,定位并读取完整的行记录;

- 存储引擎把记录交给 Server 层去检测该记录是否满足 WHERE 条件。

2) 使用 ICP 的情况下:

- 存储引擎读取索引记录(不是完整的行记录);

- 判断 WHERE 条件部分能否用索引中的列来做检查,条件不满足,则处理下一行索引记录;

- 条件满足,使用索引中的主键去定位并读取完整的行记录(就是所谓的回表);

- 存储引擎把记录交给 Server 层,Server 层检测该记录是否满足 WHERE 条件的其余部分。

2 具体示例

上面介绍了基本原理,下面使用示例,带大家更直观的进行理解(注:以下示例基于 InnoDB 存储引擎。)

首先,我们新建一张用户表(jxc_user),设置 id 为主键索引,并创建联合索引(name, age)。

376f2da2-852e-11ed-bfe3-dac502259ad0.png

我们先看一下该表主键索引的大致结构示例:

37897810-852e-11ed-bfe3-dac502259ad0.png

主键索引结构示例图 然后我们再看一下该表联合索引的大致结构示例:

37a9d7d6-852e-11ed-bfe3-dac502259ad0.png

联合索引结构示例图 如果现在有一个需求,要求检索出表中名字第一个字是张,而且年龄等于 10 岁的所有用户。示例 SQL 语句如下:

select id,name,age,tel,addr from jxc_user where name like '张%' and age=10;

根据索引最左匹配原则,上面这个 sql 语句在查索引树的时候,只能用 “张”,查到第一个满足条件的记录:id 为 1。

那接下来我们具体看一下 使用与未使用 ICP 的情况。

2.1 未使用 ICP 的情况

在 MySQL 5.6 之前,存储引擎根据联合索引先找到 name like ‘张 %’ 的主键 id(1、4),再逐一进行回表扫描,去聚簇索引找到完整的行记录,返回 server 层,server 层拿到数据后,再根据条件 age=10 对拿到的数据进行筛选。大致的示意图如下:

37decd1a-852e-11ed-bfe3-dac502259ad0.png

从上图,可以看到需要回表两次,存储引擎并不会去按照 age=10 进行过滤,相当于联合索引的另一个字段 age 在存储引擎层没有发挥作用,比较浪费。

2.2 使用 ICP 的情况

而 MySQL 5.6 以后, 存储引擎会根据(name,age)联合索引,找到 name like ‘张 %’,由于联合索引中包含 age 列,所以存储引擎直接再联合索引里按照条件 age=10 进行过滤,然后根据过滤后的数据再依次进行回表扫描。大致的示意图如下:

3817a1b2-852e-11ed-bfe3-dac502259ad0.png

从上图,可以看到只是 id=1 的数据,回表了一次。 除此之外我们还可以看一下执行计划,看到 Extra 一列里 Using index condition,就是用到了索引下推。

3841dafe-852e-11ed-bfe3-dac502259ad0.png

3 控制参数

Mysql 索引下推功能默认是开启的,可以用系统参数 optimizer_switch 来控制是否开启。

查看状态命令:

select @@optimizer_switch;

386779e4-852e-11ed-bfe3-dac502259ad0.png

关闭命令:set optimizer_switch=”index_condition_pushdown=off”;

开启命令:set optimizer_switch=”index_condition_pushdown=on”;

4 总结

回表操作:当所要查找的字段不在非主键索引树上时,需要通过叶子节点的主键值去主键索引上获取对应的行数据,这个过程称为回表操作。

索引下推:索引下推主要是减少了不必要的回表操作。对于查找出来的数据,先过滤掉不符合条件的,其余的再去主键索引树上查找。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 数据库
    +关注

    关注

    7

    文章

    3750

    浏览量

    64216
  • MySQL
    +关注

    关注

    1

    文章

    795

    浏览量

    26385
  • ICP
    ICP
    +关注

    关注

    0

    文章

    68

    浏览量

    12745

原文标题:MySQL索引下推知识分享

文章出处:【微信号:OSC开源社区,微信公众号:OSC开源社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    #硬声创作季 【MySQL调优】聚集索引与覆盖索引索引下推到底是什么

    数据库MySQL
    Mr_haohao
    发布于 :2022年09月14日 07:35:53

    MySQL索引的创建与删除

    MySQL——索引技巧以及注意事项
    发表于 10-31 09:27

    详解mysql索引

    mysql索引简介
    发表于 04-13 06:50

    mysql索引使用技巧有哪些?

    mysql索引使用技巧
    发表于 05-20 06:09

    基于MySQL索引的压力测试

    MySQL - 基于索引的压力测试
    发表于 06-13 07:57

    MySQL索引使用优化和规范

    MySQL - 索引使用优化和规范
    发表于 06-15 16:01

    MySQL索引、事务、视图介绍

    MySQL--索引、事务、视图
    发表于 06-15 07:05

    MySQL索引使用原则

    一般来说, MySQL 中的 B-Tree 索引的物理文件大多都是以 Balance Tree 的结构来存储的,也就是所有实际需要的数据都存放于 Tree 的 Leaf Node(叶子节点) ,而且
    的头像 发表于 02-11 15:17 2688次阅读
    <b class='flag-5'>MySQL</b><b class='flag-5'>索引</b>使用原则

    MySQL索引的使用问题

    MySQL 在LIKE进行模糊匹配的时候又是如何利用索引的呢?3、MySQL 到底在怎么样的情况下能够利用索引进行排序?今天,我将会用一个模型,把这些问题都一一解答,让你对
    的头像 发表于 01-06 16:13 1567次阅读

    关于MySQL索引的分类与原理及本质解析

    索引,可能让好很多人望而生畏,毕竟每次面试时候 MySQL索引一定是必问内容,哪怕先撇开面试,就在平常的开发中,对于 SQL 的优化也而是重中之重。
    的头像 发表于 04-03 11:56 1583次阅读
    关于<b class='flag-5'>MySQL</b>中<b class='flag-5'>索引</b>的分类与原理及本质解析

    一百道关于MySQL索引解答

    数据库 1. MySQL索引使用有哪些注意事项呢? 可以从三个维度回答这个问题:索引哪些情况会失效,索引不适合哪些场景,索引规则
    的头像 发表于 06-13 15:51 2059次阅读

    MySQL高级进阶:索引优化

    MySQL官方对于索引的定义:索引是帮助MySQL高效获取数据的数据结构。
    的头像 发表于 06-11 11:13 542次阅读
    <b class='flag-5'>MySQL</b>高级进阶:<b class='flag-5'>索引</b>优化

    MySQL索引的常用知识

    索引结构:B+树 索引其实是一种数据结构 注意B+树是MySQL索引默认的结构;一张表至少有一个索引(主键
    的头像 发表于 09-30 16:43 418次阅读

    导致MySQL索引失效的情况以及相应的解决方法

    导致MySQL索引失效的情况以及相应的解决方法  MySQL索引的目的是提高查询效率,但有些情况下索引可能会失效,导致查询变慢或效果不如预期
    的头像 发表于 12-28 10:01 713次阅读

    一文了解MySQL索引机制

    接触MySQL数据库的小伙伴一定避不开索引索引的出现是为了提高数据查询的效率,就像书的目录一样。 某一个SQL查询比较慢,你第一时间想到的就是“给某个字段加个索引吧”,那么
    的头像 发表于 07-25 14:05 218次阅读
    一文了解<b class='flag-5'>MySQL</b><b class='flag-5'>索引</b>机制