mysql索引优化原则:覆盖索引、最左前缀原则、索引下推
文章目录
- 前言
- 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索引优化原则:覆盖索引、最左前缀原则、索引下推相关推荐
- 【MySQL】索引原理(三):联合索引(最左前缀原则),覆盖索引,索引条件下推
准备工作,下面的演示都是基于user_innodb表: DROP TABLE IF EXISTS `user_innodb`; CREATE TABLE `user_innodb` (`id` big ...
- 我去,为什么最左前缀原则失效了?
问题 最近,在 mysql 测试最左前缀原则,发现了匪夷所思的事情.根据最左前缀原则,本来应该索引失效,走全表扫描的,但是,却发现可以正常走索引. 表结构如下( Mysql 版本 5.7.22): C ...
- MySQL 覆盖索引、最左前缀原则、索引下推
1.覆盖索引 1.1 概念 索引是高效找到行的一个方法,当能通过检索索引就可以读取想要的数据,那就不需要再到数据表中读取行了.如果一个索引包含了(或覆盖了)满足查询语句中字段与条件的数据就叫做覆盖索引 ...
- 《MySQL实战45讲》——学习笔记04-05 “深入浅出索引、最左前缀原则、索引下推优化“
04 | 深入浅出索引(上) 1. 什么是索引? 索引的出现其实就是为了提高数据查询的效率,就像书的目录一样,书有500页,每页存的都是书的内容,目录可能只有5页,只存了页码:通过目录能快速找到某个主 ...
- 【MySQL】索引优化中的最左前缀原则和索引下推
目录 一.引入 二.覆盖索引 讲接下来的问题前首先讲一下联合索引的底层存储结构长什么样?联合索引的检索过程是什么样的呢? 三.最左前缀原则 最左前缀原则的定义 四.索引下推 五.小结 一.引入 在 ...
- mysql非聚集索引区间查询_mysql的聚集索引和非聚集索引,回表查询,索引覆盖,最左前缀原则略解...
什么是聚集索引和非聚集索引 我们知道 Mysql 底层是用 B+ 树来存储索引的,且数据都存在叶子节点.对于 InnoDB 来说,它的主键索引和行记录是存储在一起的,因此叫做聚集索引(clustere ...
- 覆盖索引最左前缀原则索引下推
覆盖索引 如果执行的语句是 select ID from T where k between 3 and 5,这时只需要查 ID 的值,而 ID 的值已经在 k 索引树上了,因此可以直接提供查询结果, ...
- mysql索引最左前缀原则
mysql索引最左前缀原则 创建索引可以大大提高系统的性能. 第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性. 第二,可以大大加快数据的检索速度,这也是创建索引的最主要的原因. 第三, ...
- 数据库性能优化1——正确建立索引以及最左前缀原则
1. 索引建立的原则 用于索引的最好的备选数据列是那些出现在WHERE子句.join子句.ORDER BY或GROUP BY子句中的列. 仅仅出现在SELECT关键字后面的输出数据列列表中的数据列不是 ...
最新文章
- C#中多线程同步的Monitor理解
- Express框架(http服务器 + 路由)
- Java GUI:将JPanel添加进JScrollPane
- 解决MySQL使用LOAD导入中文数据乱码的问题
- 解析法实现一元线性回归、多元线性回归以及数据模型可视化操作
- WiFi共享精灵 - 不需路由器一键轻松把网线共享给手机、笔记本等同时无线上网...
- python爬取2019年计算机就业_2019年最新Python爬取腾讯招聘网信息代码解析
- java web mysql 登陆_javaweb登录功能实现,eclipse开发工具,mysql作为数据库
- python求职者的建议_Python 求职和建议-从认识自己出发
- 金融综合(网课+读书笔记)
- C Primer Plus 第5章 运算符、表达式和语句 5.2基本运算符
- Selenium WebDriver 与 iOS 自动化测试 (做了一些初步的工具对比)
- CSDB Blog快速备份程序-备份你自己的Blog
- 极通首次为中小企业量身定制EWEBS极速版
- Tmall商城系统后台管理订单模块分析
- 将经纬度转换为以度为单位的xy坐标
- 聊聊Java中代码优化的30个小技巧
- 【转载】阿里云域名解析将一个域名指向另一个域名
- 作品交流:数字通信同步技术资源下载
- 赶集网–免费发布信息