文章目录

  • 前言
    • round1:覆盖索引
    • round2:最左前缀原则
    • round3:索引下推
  • 小结

前言

在文章开始前,小编提出几个问题,读者可以思考一下如何回答。如果对于以下的问题,回答的模棱两可甚至根本不了解,我想这篇文章应该会合你的口味。

查询数据时如何减少回表的次数?
什么是“最左前缀原则”?解决了什么问题?
什么是“索引下推”?这种方法带来了什么好处?


round1:覆盖索引

查询数据时如何减少回表的次数?

回答这个问题前,我们要知道什么是回表?

我们都知道索引分为主键索引和非主键索。先来看看执行一条 sql,Mysql 是如何执行搜索操作的?

select * from T where k between 3 and 5

SQL执行流程:
1、在k索引树上找到索引k为3的记录,取得ID = 300;
2、再到ID索引树查询ID=300对应的R3;
3、在k索引树取下一个值k=5,取得ID=500;
4、再回到ID索引树查到ID=500对应的R4;
5、在k索引树取下一个值k=6,不满足条件,循环结束。

在这个执行过程中,回到主键索引树搜索的过程称为回表。可以看到,这个查询过程中读了k索引树的3条记录(分别是索引3,5,6),回表了两次(分别是300,500)。
在这个例子中,由于查询结果所需要的数据只在主键索引上有,所以不得不回表。那么,有没有可能经过索引优化,避免回表过程呢?

答案是肯定的,覆盖索引可以避免回表过程。如果我们执行的语句是:

select id from T where k between 3 and 5

此时,只需要查询 id 的值,而 id 的值已经在k索引树上了,因此,可以直接返回查询结果,避免了回表过程。也就是说:在这个查询里面,索引 k 已经 “覆盖了” 我们的查询请求,我们称为覆盖索引。

由于覆盖索引可以减少树的搜索次数,显著提升查询性能,所以使用覆盖索引是一个常用的性能优化手段。


round2:最左前缀原则

了解什么是最左前缀原则前,先来看看什么是联合索引?

两个或更多个列上的索引被称作联合索引,联合索引又叫复合索引。如:User 表的 name 和 age 加联合索引就是(name,city),而最左前缀原则指的是,如果查询的时候查询条件精确匹配索引的左边连续一列或者几列,则此列就可以被匹配到。例如:

select * from user where name = xx and age = xx;   # 可以命中索引
select * from user where name = xx;                    # 可以命中索引
select * from user where city = xx;                    # 无法命中索引

这里,要注意的是,查询的时候两个条件都用上了,但是顺序不同,如 city = xx and name = xx ,那么现在的查询引擎会自动优化为匹配联合索引的顺序,这样是能够命中索引的。

举例说明“最左前缀原则”的使用场景,现在要求根据市民的身份证号查询姓名,由于这种查询比较高频,所以可以建立(身份证号,姓名)的联合索引。但如果现在出现了新的需求,要求根据市民的身份证号查询家庭住址,但这种情况不算高频,但也不能全盘扫描,那新建联合索引?但又不是高频请求,新建联合索引是不是有些浪费?那应该怎么办???

当然是“最左前缀原则”派上用场了,还记得“最左前缀原则” 吗?如果查询条件可以精确匹配索引的左边连续一列或者几列,则此列就可以被匹配到。这样,利用(身份证号)去查询家庭住址,就可以解决上面的问题了。

基于上面对最左前缀索引的说明,我们来讨论一个问题:在建立联合索引的时候,如何安排索引内的字段顺序?

这里我们的评估标准是,索引的复用能力。因为可以支持最左前缀,所以当已经有了(a,b)这个联合索引后,一般就不需要单独在a上建立索引了。因此,第一原则是,如果通过调整顺序,可以少维护一个索引,那么这个顺序往往就是需要优先考虑采用的。


round3:索引下推

上一段我们说到满足最左前缀原则的时候,最左前缀可以用于在索引中定位记录。这时,你可能要问,那些不符合最左前缀的部分,会怎么样呢?

我们以市民表的联合索引(name, age)为例。如果现在有一个需求:检索出表中“名字第一个字是张,而且年龄是10岁的所有男孩”。那么,SQL语句是这么写的:

select * from tuser where name like '张%' and age=10 and ismale=1;

现在,我们已经知道了 "最左前缀原则”,所以,在搜索索引树时,只能用“张”,找到第一个满足条件的记录ID3,总比全盘扫描要好。
然后呢?
我们需要对比其他条件是否满足。
在MySQL 5.6之前,只能从ID3开始一个个回表。到主键索引上找出数据行,再对比字段值。

而MySQL 5.6 引入的索引下推优化(index condition pushdown), 可以在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数。

例如,看看使用索引下推优化前的示意图


使用索引下推优化后的示意图

其中,每条虚线代表一次回表,两张图对比,很容易看出优化后的回表次数减少了。两种方式的区别是:InnoDB在(name,age)索引内部就判断了age是否等于10,对于不等于10的记录,直接判断并跳过。在我们的这个例子中,只需要对ID4、ID5这两条记录回表取数据判断,就只需要回表2次。


小结

本篇文章讲述了 “覆盖索引”、“最左前缀原则”、“索引下推”三种索引优化方式,其中“覆盖索引”的出现是为了减少索引回表次数,提高查询效率。“最左前缀原则”可以让我们更好的利用索引,知道了如何设计出更高效的索引。“索引下推” 是在回表前进行数据的判断,为了减少不能匹配最左前缀原则的数据查询的回表次数。

在满足语句需求的情况下, 尽量少地访问资源是数据库设计的重要原则之一。我们在使用数据库的时候,尤其是在设计表结构时,也要以减少资源消耗作为目标。

mysql索引优化原则:覆盖索引、最左前缀原则、索引下推相关推荐

  1. 【MySQL】索引原理(三):联合索引(最左前缀原则),覆盖索引,索引条件下推

    准备工作,下面的演示都是基于user_innodb表: DROP TABLE IF EXISTS `user_innodb`; CREATE TABLE `user_innodb` (`id` big ...

  2. 我去,为什么最左前缀原则失效了?

    问题 最近,在 mysql 测试最左前缀原则,发现了匪夷所思的事情.根据最左前缀原则,本来应该索引失效,走全表扫描的,但是,却发现可以正常走索引. 表结构如下( Mysql 版本 5.7.22): C ...

  3. MySQL 覆盖索引、最左前缀原则、索引下推

    1.覆盖索引 1.1 概念 索引是高效找到行的一个方法,当能通过检索索引就可以读取想要的数据,那就不需要再到数据表中读取行了.如果一个索引包含了(或覆盖了)满足查询语句中字段与条件的数据就叫做覆盖索引 ...

  4. 《MySQL实战45讲》——学习笔记04-05 “深入浅出索引、最左前缀原则、索引下推优化“

    04 | 深入浅出索引(上) 1. 什么是索引? 索引的出现其实就是为了提高数据查询的效率,就像书的目录一样,书有500页,每页存的都是书的内容,目录可能只有5页,只存了页码:通过目录能快速找到某个主 ...

  5. 【MySQL】索引优化中的最左前缀原则和索引下推

    目录 一.引入 二.覆盖索引 ​ 讲接下来的问题前首先讲一下联合索引的底层存储结构长什么样?联合索引的检索过程是什么样的呢? 三.最左前缀原则 最左前缀原则的定义 四.索引下推 五.小结 一.引入 在 ...

  6. mysql非聚集索引区间查询_mysql的聚集索引和非聚集索引,回表查询,索引覆盖,最左前缀原则略解...

    什么是聚集索引和非聚集索引 我们知道 Mysql 底层是用 B+ 树来存储索引的,且数据都存在叶子节点.对于 InnoDB 来说,它的主键索引和行记录是存储在一起的,因此叫做聚集索引(clustere ...

  7. 覆盖索引最左前缀原则索引下推

    覆盖索引 如果执行的语句是 select ID from T where k between 3 and 5,这时只需要查 ID 的值,而 ID 的值已经在 k 索引树上了,因此可以直接提供查询结果, ...

  8. mysql索引最左前缀原则

    mysql索引最左前缀原则 创建索引可以大大提高系统的性能. 第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性. 第二,可以大大加快数据的检索速度,这也是创建索引的最主要的原因. 第三, ...

  9. 数据库性能优化1——正确建立索引以及最左前缀原则

    1. 索引建立的原则 用于索引的最好的备选数据列是那些出现在WHERE子句.join子句.ORDER BY或GROUP BY子句中的列. 仅仅出现在SELECT关键字后面的输出数据列列表中的数据列不是 ...

最新文章

  1. C#中多线程同步的Monitor理解
  2. Express框架(http服务器 + 路由)
  3. Java GUI:将JPanel添加进JScrollPane
  4. 解决MySQL使用LOAD导入中文数据乱码的问题
  5. 解析法实现一元线性回归、多元线性回归以及数据模型可视化操作
  6. WiFi共享精灵 - 不需路由器一键轻松把网线共享给手机、笔记本等同时无线上网...
  7. python爬取2019年计算机就业_2019年最新Python爬取腾讯招聘网信息代码解析
  8. java web mysql 登陆_javaweb登录功能实现,eclipse开发工具,mysql作为数据库
  9. python求职者的建议_Python 求职和建议-从认识自己出发
  10. 金融综合(网课+读书笔记)
  11. C Primer Plus 第5章 运算符、表达式和语句 5.2基本运算符
  12. Selenium WebDriver 与 iOS 自动化测试 (做了一些初步的工具对比)
  13. CSDB Blog快速备份程序-备份你自己的Blog
  14. 极通首次为中小企业量身定制EWEBS极速版
  15. Tmall商城系统后台管理订单模块分析
  16. 将经纬度转换为以度为单位的xy坐标
  17. 聊聊Java中代码优化的30个小技巧
  18. 【转载】阿里云域名解析将一个域名指向另一个域名
  19. 作品交流:数字通信同步技术资源下载
  20. 赶集网–免费发布信息

热门文章

  1. 研究生学python方便写论文嘛_研究生写论文,千万不要给自己挖坑!
  2. 基于RetinaFace的口罩人脸检测算法
  3. Kafka高吞吐原理及如何保证不丢失不重复消费
  4. 量化交易巨变文艺复兴大幅削趋追交策
  5. snprintf与_snprintf区别
  6. 2014暑假总结——美好的事情即将发生
  7. android开发板只有网口和串口如何使用android studio进行调试
  8. 全球及中国户外餐具行业竞争格局及发展前景规模预测报告2021-2027年版
  9. FFplay文档解读-25-音频源,音频接收器
  10. sqlite3 小白基操