InnoDB中索引分类

我们都知道InnoDB索引结构是B+树组织的,但是根据数据存储形式不同可以分为两类,分别是聚簇索引二级索引

ps:有些同学还听过非聚簇索引辅助索引,其他它们都是一个意思,本文统一称为二级索引

聚簇索引

聚簇索引默认是由主键构成,如果没有定义主键,InnoDB会选择非空的唯一索引代替,还是没有的话,InnoDB隐式的定义一个主键来作为聚簇索引

其实聚簇索引的本质就是主键索引

因为每张表只能拥有一个主键字段,所以每张表只有一个聚簇索引

另外聚簇索引还有一个特点,表的数据和主键是一起存储的,它的叶子节点存放的是整张表的行数据(树的最后一层),叶子节点又称为数据页

很简单记住一句话:找到了索引就找到了行数据,那么这个索引就是聚簇索引。

如果这里无法理解的话,可以去补下阿星的前两篇文章

  • InnoDB原理篇:聊聊数据页变成索引这件事

  • InnoDB原理篇:为什么使用索引会变快?

二级索引

知道了聚簇索引,再来看看二级索引是什么,简单概括,除主键索引以外的索引,都是二级索引,像我们平时建立的联合索引、前缀索引、唯一索引等。

二级索引的叶子节点存储的是索引值+主键id

所以二级索引与聚簇索引的区别在于叶子节点是否存放整行记录

也就意味着,仅仅靠二级索引无法拿到完整行数据,只能拿到id信息。

那二级索引应该如何拿到完整行数据呢?

索引的查询

假设,我们有一个主键列为id的表,表中有字段kk上有索引。这个表的建表语句是:

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索引变更成kname的联合索引。

这个联合索引就有意义了,它可以在高频场景用到覆盖索引,不再需要回表查整行记录,减少语句的执行时间。

ps:设计索引时,请遵守最左原则匹配

索引下推

此时我们再建立一个namek的联合索引。

执行select k from T where name like '张%' and k = 2语句。

首先会在namek树中用找到第一条件满足条件的记录id = 100,然后从id = 100开始遍历一个个回表,到主键索引上找出行记录,再对比k字段值,是不是十分操蛋。

可以看到总共回表6

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

总共回表0次。

小结

本篇文章到这里就结束了,今天和大家聊了聚簇索引、二级索引、回表、覆盖索引、索引下推等知识,可以看到,在满足语句需求的情况下,尽量少地访问资源是数据库设计的重要原则之一,由于篇幅有限,很多内容还没展开,后续阿星会和大家聊聊如何设计索引。

有道无术,术可成;有术无道,止于术

欢迎大家关注Java之道公众号

好文章,我在看❤️

InnoDB原理篇:如何用好索引相关推荐

  1. InnoDB原理篇:为什么使用索引会变快?

    索引 假设给你一本非常厚的<Java编程思想>阅读,没有目录,你想快速找到某一个章节的知识点,那估计得找一会了,如果有目录就不一样. 索引其实就是为了提高数据查询的效率,就像书的目录一样, ...

  2. InnoDB原理篇:Change Buffer是如何提升索引性能的?

    前言 相信很多小伙伴设计索引时,考虑更多的是索引是否能覆盖大部分的业务场景,却忽略了索引的性能. 什么?不同的索引,性能还不一样? 是的,这要从change buffer说起.   Change Bu ...

  3. InnoDB原理篇:聊聊数据页变成索引这件事

    前言 每个缓存页对应一个数据页,今天以数据页为起点,来聊聊InnoDB的索引. 数据页 我们都知道平时执行crud的时候,都会从磁盘上加载数据页到Buffer Pool的缓存页里去,更新缓存页后,由异 ...

  4. Mysql—索引①:原理篇

    目录 什么是索引? 索引的优点和缺点 数据页 什么是数据页 页与页之间的连接结构(双链表) 单页查找 多页查找 聚簇索引,二级索引(非聚簇索引.辅助索引) 聚簇索引 非聚簇索引 聚簇索引与非聚簇索引比 ...

  5. 高并发之存储篇:关注下索引原理和优化吧!躲得过实践,躲不过面试官!

    以MySQL的InnoDB索引为主,看完需要5分钟 本文内容预览: 为什么Kafka不需要我们关心索引,而Mysql却需要? Mysql数据怎么被组织 2.1 数据记录最小单位:行 2.2 与磁盘最小 ...

  6. 一篇读懂聚集索引、非聚集索引、覆盖索引的工作原理!

    作者:PostTruth 「数据库」和「数据库索引」这两个东西是在服务器端开发领域应用最为广泛的两个概念,熟练使用数据库和数据库索引是开发人员在行业内生存的必备技能. 使用索引很简单,只要能写创建表的 ...

  7. 公众号1200篇文章分类和索引

    承蒙读者朋友们的关照,截止到今天,杂货铺的文章已经积累到了1200篇,其中有超过2/3的文章都是原创的,即使是转载,我给的底线是一定要加些自己的见解,因为至少得让读者了解到这篇文章的价值,而不仅仅是文 ...

  8. mysql索引下推原理_MySQL:好好的索引,为什么要下推?

    前段时间有读者提议讲讲索引下推,这期就把这事儿安排上.多余的前言就不赘述了,我们直接开始. 列位坐好! - 思维导图 - 回表操作 对于数据库来说,只要涉及到索引,必然绕不过去回表操作.当然这也是我们 ...

  9. Mysql原理篇之表空间---05

    Mysql原理篇之表空间---05 前言 回顾 页面类型 页面通用部分 独立表空间结构 区(extent)的概念 段(segment)的概念 区的分类 整理 XDES Entry链表 链表基节点 链表 ...

最新文章

  1. 英伟达A100可达V100的3.5倍?
  2. 云计算、大数据、物联网等IT技术发展趋势
  3. discuz修改用户uid_你知道Linux中的UID和GID的含义吗
  4. spring jaxb_自定义Spring命名空间使JAXB变得更容易
  5. 基于Linux和MiniGUI的嵌入式系统软件开发指南(四)
  6. python_83_random_应用验证码
  7. 用matlab画声偶级辐射,matlab结题报告(电偶极子的辐射场)
  8. mysql innodb缓冲池_InnoDB 缓冲池
  9. ecshop send.php on line 71,搭建LNMP发布ecshop系统及压测启用opcache缓存与否的情况
  10. 如何使用 jdk帮助文档
  11. Chrome插件-Dark reader,护眼的黑暗模式浏览器
  12. 【前端面经】面试:最快最全面的渗透应聘者真实水平
  13. 学编程一定要数学很好吗?看到网友这样说,我松了一口气 ...
  14. 基于QT的英文文献的编辑与检索系统的实现
  15. linux 繁体中文转为简体,linux - 安装OpenCC(简体繁体转换)
  16. Bayes | 贝叶斯统计入门杂记
  17. 回忆着你对我的承诺、一切的一切在那个夏季散了
  18. 2020黑客大会——深入浅出现代Windows Rootkit
  19. 华为“721法则”:如何让新员工快速融入“狼群”
  20. Xmind使用tips

热门文章

  1. HTML期末作业-美食网站
  2. css3书页翻转,CSS3实现3D翻书效果
  3. 查询php 输出表格,php输出excel表格数据-PHP如何将查询出来的数据导出成excel表格(最好做......
  4. python魔术方法abstract_python学习之面向对象高级特性和魔术方法
  5. bmf mysql_bmf 的动态 - SegmentFault 思否
  6. 用python做一张图片_如何用python下载一张图片
  7. (数据库系统概论|王珊)第七章数据库设计-第四节:逻辑结构设计
  8. (王道408考研操作系统)第二章进程管理-第二节4:调度算法详解2(RR、HPF和MFQ)
  9. Qt之系统托盘(QSystemTrayIcon详解)
  10. Linux 主机超全渗透测试命令汇总