InnoDB原理篇:如何用好索引
InnoDB中索引分类
我们都知道InnoDB
索引结构是B+
树组织的,但是根据数据存储形式不同可以分为两类,分别是聚簇索引与二级索引。
ps:有些同学还听过非聚簇索引和辅助索引,其他它们都是一个意思,本文统一称为二级索引。
聚簇索引
聚簇索引默认是由主键构成,如果没有定义主键,InnoDB
会选择非空的唯一索引代替,还是没有的话,InnoDB
会隐式的定义一个主键来作为聚簇索引。
其实聚簇索引的本质就是主键索引。
因为每张表只能拥有一个主键字段,所以每张表只有一个聚簇索引。
另外聚簇索引还有一个特点,表的数据和主键是一起存储的,它的叶子节点存放的是整张表的行数据(树的最后一层),叶子节点又称为数据页。
很简单记住一句话:找到了索引就找到了行数据,那么这个索引就是聚簇索引。
如果这里无法理解的话,可以去补下阿星的前两篇文章
InnoDB原理篇:聊聊数据页变成索引这件事
InnoDB原理篇:为什么使用索引会变快?
二级索引
知道了聚簇索引,再来看看二级索引是什么,简单概括,除主键索引以外的索引,都是二级索引,像我们平时建立的联合索引、前缀索引、唯一索引等。
二级索引的叶子节点存储的是索引值+主键id
。
所以二级索引与聚簇索引的区别在于叶子节点是否存放整行记录。
也就意味着,仅仅靠二级索引无法拿到完整行数据,只能拿到id
信息。
那二级索引应该如何拿到完整行数据呢?
索引的查询
假设,我们有一个主键列为id
的表,表中有字段k
,k
上有索引。这个表的建表语句是:
create table T(
id int primary key,
k int not null,
name varchar(16),
index (k))engine=InnoDB;
表中有5
条记录(id,k)
,值分别为(100,1)、(200,2)、(300,3)、(500,5)、(600,6)
,此时会有两棵树,分别是主键id
的聚簇索引和字段k
的二级索引,简化的树结构图如下
回表
我们执行一条主键查询语句select * from T where id = 100
,只需要搜索id
聚簇索引树就能查询整行数据。
接着再执行一条select * from T where k = 1
,此时要搜索k
的二级索引树,具体过程如下
在 k 索引树上找 k = 1的记录,取得 id = 100
再到聚簇索引树查 id = 100 对应的行数据
回到 k 索引树取下一个值 k = 2,不满足条件,循环结束
上图中,回到聚簇索引树搜索的过程,我们称为回表。
也就是说,基于二级索引的查询需要多扫描一棵聚簇索引树,因此在开发中尽量使用主键查询。
索引覆盖
可是有时候我们确实需要使用二级索引查询,有没有办法避免回表呢?
办法是有的,但需要结合业务场景来使用,比如本次查询只返回id
值,查询语句可以这样写select id from T where k = 1
,过程如下
在 k 索引树上找 k = 1的记录,取得 id = 100
返回 id 值
回到 k 索引树取下一个值 k = 2,不满足条件,循环结束
在这个查询中,索引k
已经覆盖了我们的查询需求,不需要回表,这个操作称为覆盖索引。
由于覆盖索引可以减少树的搜索次数,显著提升查询性能,所以使用覆盖索引是一个常用的性能优化手段。
假设现在有一个高频的业务场景,根据k
查询,返回name
,我们可以把k
索引变更成k
与name
的联合索引。
这个联合索引就有意义了,它可以在高频场景用到覆盖索引,不再需要回表查整行记录,减少语句的执行时间。
ps:设计索引时,请遵守最左原则匹配
索引下推
此时我们再建立一个name
与k
的联合索引。
执行select k from T where name like '张%' and k = 2
语句。
首先会在name
与k
树中用张找到第一条件满足条件的记录id = 100
,然后从id = 100
开始遍历一个个回表,到主键索引上找出行记录,再对比k
字段值,是不是十分操蛋。
可以看到总共回表了6
次
不过在MySQL 5.6
版本引入的索引下推,可以在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数。
总共回表0
次。
小结
本篇文章到这里就结束了,今天和大家聊了聚簇索引、二级索引、回表、覆盖索引、索引下推等知识,可以看到,在满足语句需求的情况下,尽量少地访问资源是数据库设计的重要原则之一,由于篇幅有限,很多内容还没展开,后续阿星会和大家聊聊如何设计索引。
有道无术,术可成;有术无道,止于术
欢迎大家关注Java之道公众号
好文章,我在看❤️
InnoDB原理篇:如何用好索引相关推荐
- InnoDB原理篇:为什么使用索引会变快?
索引 假设给你一本非常厚的<Java编程思想>阅读,没有目录,你想快速找到某一个章节的知识点,那估计得找一会了,如果有目录就不一样. 索引其实就是为了提高数据查询的效率,就像书的目录一样, ...
- InnoDB原理篇:Change Buffer是如何提升索引性能的?
前言 相信很多小伙伴设计索引时,考虑更多的是索引是否能覆盖大部分的业务场景,却忽略了索引的性能. 什么?不同的索引,性能还不一样? 是的,这要从change buffer说起. Change Bu ...
- InnoDB原理篇:聊聊数据页变成索引这件事
前言 每个缓存页对应一个数据页,今天以数据页为起点,来聊聊InnoDB的索引. 数据页 我们都知道平时执行crud的时候,都会从磁盘上加载数据页到Buffer Pool的缓存页里去,更新缓存页后,由异 ...
- Mysql—索引①:原理篇
目录 什么是索引? 索引的优点和缺点 数据页 什么是数据页 页与页之间的连接结构(双链表) 单页查找 多页查找 聚簇索引,二级索引(非聚簇索引.辅助索引) 聚簇索引 非聚簇索引 聚簇索引与非聚簇索引比 ...
- 高并发之存储篇:关注下索引原理和优化吧!躲得过实践,躲不过面试官!
以MySQL的InnoDB索引为主,看完需要5分钟 本文内容预览: 为什么Kafka不需要我们关心索引,而Mysql却需要? Mysql数据怎么被组织 2.1 数据记录最小单位:行 2.2 与磁盘最小 ...
- 一篇读懂聚集索引、非聚集索引、覆盖索引的工作原理!
作者:PostTruth 「数据库」和「数据库索引」这两个东西是在服务器端开发领域应用最为广泛的两个概念,熟练使用数据库和数据库索引是开发人员在行业内生存的必备技能. 使用索引很简单,只要能写创建表的 ...
- 公众号1200篇文章分类和索引
承蒙读者朋友们的关照,截止到今天,杂货铺的文章已经积累到了1200篇,其中有超过2/3的文章都是原创的,即使是转载,我给的底线是一定要加些自己的见解,因为至少得让读者了解到这篇文章的价值,而不仅仅是文 ...
- mysql索引下推原理_MySQL:好好的索引,为什么要下推?
前段时间有读者提议讲讲索引下推,这期就把这事儿安排上.多余的前言就不赘述了,我们直接开始. 列位坐好! - 思维导图 - 回表操作 对于数据库来说,只要涉及到索引,必然绕不过去回表操作.当然这也是我们 ...
- Mysql原理篇之表空间---05
Mysql原理篇之表空间---05 前言 回顾 页面类型 页面通用部分 独立表空间结构 区(extent)的概念 段(segment)的概念 区的分类 整理 XDES Entry链表 链表基节点 链表 ...
最新文章
- 英伟达A100可达V100的3.5倍?
- 云计算、大数据、物联网等IT技术发展趋势
- discuz修改用户uid_你知道Linux中的UID和GID的含义吗
- spring jaxb_自定义Spring命名空间使JAXB变得更容易
- 基于Linux和MiniGUI的嵌入式系统软件开发指南(四)
- python_83_random_应用验证码
- 用matlab画声偶级辐射,matlab结题报告(电偶极子的辐射场)
- mysql innodb缓冲池_InnoDB 缓冲池
- ecshop send.php on line 71,搭建LNMP发布ecshop系统及压测启用opcache缓存与否的情况
- 如何使用 jdk帮助文档
- Chrome插件-Dark reader,护眼的黑暗模式浏览器
- 【前端面经】面试:最快最全面的渗透应聘者真实水平
- 学编程一定要数学很好吗?看到网友这样说,我松了一口气 ...
- 基于QT的英文文献的编辑与检索系统的实现
- linux 繁体中文转为简体,linux - 安装OpenCC(简体繁体转换)
- Bayes | 贝叶斯统计入门杂记
- 回忆着你对我的承诺、一切的一切在那个夏季散了
- 2020黑客大会——深入浅出现代Windows Rootkit
- 华为“721法则”:如何让新员工快速融入“狼群”
- Xmind使用tips
热门文章
- HTML期末作业-美食网站
- css3书页翻转,CSS3实现3D翻书效果
- 查询php 输出表格,php输出excel表格数据-PHP如何将查询出来的数据导出成excel表格(最好做......
- python魔术方法abstract_python学习之面向对象高级特性和魔术方法
- bmf mysql_bmf 的动态 - SegmentFault 思否
- 用python做一张图片_如何用python下载一张图片
- (数据库系统概论|王珊)第七章数据库设计-第四节:逻辑结构设计
- (王道408考研操作系统)第二章进程管理-第二节4:调度算法详解2(RR、HPF和MFQ)
- Qt之系统托盘(QSystemTrayIcon详解)
- Linux 主机超全渗透测试命令汇总