小白也能懂的Mysql数据库索引详解
核心概念
- 主键索引/二级索引
- 聚簇索引/非聚簇索引
- 回表/索引覆盖
- 索引下推
- 联合索引/最左联合匹配
- 前缀索引
- explain
一、[索引定义]
1.索引定义
在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法。这种数据结构,就是索引。
2.索引的数据结构
- B树 / B+树 (mysql的innodb引擎默认选择B+树作为索引的数据结构)
- HASH表
- 有序数组
3.选用B+树而不选用B树作为索引
- B树的数据结构:record记录存放在树的节点中
- B+树的数据结构: record记录只存放在树的叶子节点中
- 假设一条数据大小1KB,索引大小16B,数据库采用磁盘数据页存储,磁盘页默认大小是16K。同样三次IO:
- B树能获取16*16*16=4096条数据
- B+树能够获取1000*1000*1000=10亿条数据
二、[索引类型]
1.主键索引和二级索引
主键索引:索引的叶子节点是数据行
二级索引:索引的叶子节点是KEY字段加主键索引,因此,通过二级索引询首先查到是主键值,然后InnoDB再根据查到的主键值通过主键索引找到相应的数据块。
innodb的主索引文件上 直接存放该行数据,称为聚簇索引,次索引指向对主键的引用
myisam中, 主索引和次索引,都指向物理行(磁盘位置).
2.聚簇索引和非聚簇索引
- 聚簇索引是对磁盘上实际数据重新组织以按指定的一个或多个列的值排序的算法。特点是存储数据的顺序和索引顺序一致。一般情况下主键会默认创建聚簇索引,且一张表只允许存在一个聚簇索引(理由:数据一旦存储,顺序只能有一种)上图可以看出innodb的一级索引和二级索引均是聚簇索引
- 相较于聚簇索引的叶子点击是数据记录,非聚簇索引的叶子节点是指向数据记录的指针。非聚簇索引与聚簇索引最大的不同就是数据记录的顺序跟索引是不一致的,因此在数据
3.聚簇索引优劣
优势: 根据主键查询条目比较少时,不用回行(数据就在主键节点下)
劣势: 如果碰到不规则数据插入时,造成频繁的页分裂。
三、[索引概念引申]
1.回表
回表的概念涉及到主键索引和非主键索引的查询区别
- 如果语句是
select * from T where ID=500
,即主键查询,则只需要搜索 ID 这棵树。 - 如果语句是
select * from T where k=5
,即非主键索引查询,则需要先搜索 k 索引树,得到 ID 的值为 500,再到 ID 索引树搜索一次。 - 从非主键索引回到主键索引的过程称为回表。
基于非主键索引的查询需要多扫描一棵索引树。因此,我们在应用中应该尽量使用主键查询。而从存储空间的角度讲,因为非主键索引树的叶结点存放的是主键的值,那么,应该考虑让主键的字段尽量短,这样非主键索引的叶子结点就越小,非主键索引占用的空间也就越小。一般情况下,建议创建一个自增主键,这样非主键索引占用的空间最小。
2.索引覆盖
- 如果where子句中的一个条件是非主键索引,那么查询的时候,先通过非主键索引定位到主键索引(主键位于非主键索引搜索树的叶子节点);然后通过主键索引定位到查询的内容。在这个过程中,回到主键索引树的过程,称为回表。
- 但是当我们的查询内容是主键值,那么可以直接提供查询结果,不需要回表。也就是说,在这个查询里,非主键索引 已经 “覆盖了” 我们的查询需求,故称为覆盖索引。
- 覆盖索引就是从辅助索引中就能直接得到查询结果,而不需要回表到一级索引中进行再次查询,所以可以减少搜索次数(不需要从辅助索引树回表到聚簇索引树),或者说减少 IO 操作(通过辅助索引树可以一次性从磁盘载入更多节点),从而提升性能。
3.联合索引
联合索引是指对表上的多个列进行索引。
场景一:
联合索引 (a, b) 是根据 a, b 进行排序(先根据 a 排序,如果 a 相同则根据 b 排序)。因此,下列语句可以直接使用联合索引得到结果(事实上,也就是用到了最左前缀原则)
select … from xxx where a=xxx;
select … from xxx where a=xxx order by b;
而下列语句则不能使用联合查询:
select … from xxx where b=xxx;
场景二:
对于联合索引 (a, b, c),下列语句同样可以直接通过联合索引得到结果:
select … from xxx where a=xxx order by b;
select … from xxx where a=xxx and b=xxx order by c;
而下列语句则不行,需要执行一次 filesort 排序操作。
select … from xxx where a=xxx order by c;
总结:
以联合索引(a,b,c)为例,建立这样的索引相当于建立了索引a、ab、abc三个索引。一个索引顶三个索引当然是好事,毕竟每多一个索引,都会增加写操作的开销和磁盘空间的开销。
4.最左匹配原则
- 从上面联合索引的例子,可以体会到最左前缀原则。
- 不只是索引的全部定义,只要满足最左前缀,就可以利用索引来加速检索。这个最左前缀可以是联合索引的最左 N 个字段,也可以是字符串索引的最左 M 个字符。利用索引的 “最左前缀” 原则来定位记录,避免重复定义索引。
- 因此,基于最左前缀原则,我们在定义联合索引的时候,考虑如何安排索引内的字段顺序就至关重要了!评估的标准就是索引的复用能力,比如,当已经有了 (a,b) 字段的索引,一般就不需要再单独在 a 上建立索引了。
5.索引下推
MySQL 5.6 引入了索引下推优化,可以在索引遍历过程中,对索引中包含的字段先做判断,过滤掉不符合条件的记录,减少回表字数。
- 建表
CREATE TABLE `test` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增主键',
`age` int(11) NOT NULL DEFAULT '0',
`name` varchar(255) CHARACTER SET utf8 NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `idx_name_age` (`name`,`age`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
SELECT * from user where name like '陈%'
最左匹配原则,命中idx_name_age索引SELECT * from user where name like '陈%' and age=20
- 5.6版本之前,先根据name索引(此时是忽略
age=20
这个条件的),匹配2条记录,然后找到对应的2个id。回表之后,在根据age=20进行过滤 - 5.6版本之后,会加入索引下推,在根据name匹配到2条数据之后,此时不会忽略
age=20
条件,在回表之前就会根据age进行过滤。此即索引下推,可以减少回表的数据量,增加查询性能
- 5.6版本之前,先根据name索引(此时是忽略
6.前缀索引
当索引是很长的字符序列时,这个索引将会很占内存,而且会很慢,这时候就会用到前缀索引了。通常可以索引开始的几个字符,而不是全部值,以节约空间并得到好的性能。所谓的前缀索引就是使用索引的前面几个字母作为索引,但是要降低索引的重复率,索引我们还必须要判断前缀索引的重复率。
- 先计算当前字符串字段的唯一性占比:
select 1.0*count(distinct name)/count(*) from test
- 在计算不同前缀的唯一性占比:
select 1.0*count(distinct left(name,1))/count(*) from test
取name字符串第一个作为前缀索引的占比select 1.0*count(distinct left(name,2))/count(*) from test
取name字符串前两个作为前缀索引的占比- ...
- 当
left(str, n)
的n不在显著增加时,此时可以选取n作为前缀索引的截取数 - 创建索引
alter table test add key(name(n));
四、[查看索引]
当我们添加索引之后,如何去查看索引呢?又或者执行语句的时候执行的特别慢,我们如何去排查呢?
explain 通常用于查看索引是否生效。
当我们获得慢查询的日志之后,查看日志,观察那些语句执行是慢查询,在该语句之前加上 explain 再次执行,explain 会在查询上设置一个标志,当执行查询时,这个标志会使其返回关于在执行计划中每一步的信息,而不是执行该语句。它会返回一行或多行信息,显示出执行该计划中的每一部分和执行次序.
explain 执行语句返回的重要字段:
- type:显示是搜索方式(全表扫描或者索引扫描)
- key:使用的索引字段,未使用则是 null
explain的 type字段:
- ALL: 全表扫描
- index: 索引全扫描
- range: 索引范围扫描
- ref: 使用非唯一索引扫描
- eq_ref: 使用唯一索引扫描
更多惊喜
我还将定期分享:
最新互联网资讯:让你时刻掌握行业动态。
AI前沿新闻:紧跟技术潮流,不断提升自我。
技术分享与职业发展:助你在职业生涯中走得更远、更稳。
程序员生活趣事:让你在忙碌的工作之余找到共鸣与乐趣。
关注回复【1024】惊喜等你来拿!
敬请关注【程序员世杰】
小白也能懂的Mysql数据库索引详解的更多相关文章
- MySQL数据库优化详解(收藏)
MySQL数据库优化详解 mysql表复制 复制表结构+复制表数据mysql> create table t3 like t1;mysql> insert into t3 select * ...
- 如何查看mysql数据库的引擎/MySQL数据库引擎详解
一般情况下,mysql会默认提供多种存储引擎,你可以通过下面的查看: 看你的mysql现在已提供什么存储引擎:mysql> show engines; 看你的mysql当前默认的存储引擎:mys ...
- MySQL 联合索引详解
MySQL 联合索引详解 联合索引又叫复合索引.对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分.例如索引是key index (a,b,c ...
- MySQL数据库备份详解
原文:MySQL数据库备份详解 对于任何数据库来说,备份都是非常重要的 数据库复制不能取代备份的作用 比如我们由于误操作,在主数据库上删除了一些数据,由于主从复制的时间很短,在发现时,从数据库上的数据 ...
- MariaDB 数据库索引详解(9)
MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可MariaDB的目的是完全兼容MySQL,包括API和命令行,MySQL由于现在闭源了,而能轻松成为MySQ ...
- MySQL数据库引擎详解
作为Java程序员,MySQL数据库大家平时应该都没少使用吧,对MySQL数据库的引擎应该也有所了解,这篇文章就让我详细的说说MySQL数据库的Innodb和MyIASM两种引擎以及其索引结构.也来巩 ...
- MySQL数据库基础详解(非原创)
文章大纲 一.数据库简介二.Mysql数据库简介三.Mysql安装与服务启动(Windows版本)四.Mysql图形化工具五.Mysql存储引擎精讲六.Mysql数据类型介绍七.Mysql主要专业名称 ...
- python接口自动化(三十八)-python操作mysql数据库(详解)
简介 现在的招聘要求对QA人员的要求越来越高,测试的一些基础知识就不必说了,来说测试知识以外的,会不会一门或者多门开发与语言,能不能读懂代码,会不会Linux,会不会搭建测试系统,会不会常用的数据库, ...
- MySQL数据库事务详解
微信公众号[程序员江湖] 作者黄小斜,斜杠青年,某985硕士,阿里 Java 研发工程师,于 2018 年秋招拿到 BAT 头条.网易.滴滴等 8 个大厂 offer,目前致力于分享这几年的学习经验. ...
- (7) MySQL数据库备份详解
对于任何数据库来说,备份都是非常重要的 数据库复制不能取代备份的作用 比如我们由于误操作,在主数据库上删除了一些数据,由于主从复制的时间很短,在发现时,从数据库上的数据可能也已经被删除了, 我们不能使 ...
随机推荐
- SpringBoot项目预加载数据——ApplicationRunner、CommandLineRunner、InitializingBean 、@PostConstruct区别
0.参考.业务需求 参考: https://www.cnblogs.com/java-chen-hao/p/11835120.html#_label1 https://zhuanlan.zhihu.c ...
- 01二分 [AGC006D] Median Pyramid Hard + P2824 [HEOI2016/TJOI2016] 排序
[AGC006D] Median Pyramid Hard 考虑对于一个长度为 2n + 1 的 01 序列 b 如何快速确定堆顶元素. _ _ _ _ x _ _ _ 0 x _ _ 0 0 x _ ...
- 1.13~1.14&&放假寄
1.13 3点就放了,手机在机房就能拿到,我为了给手机充会电又多留了一会(事实证明这挺对的) 因为我们是 化微机的班,老师收手机都放在一个箱子里,要有人负责把剩下的手机搬到教室,我走得晚还被当成免费劳 ...
- 简说Python之flask初体验
目录 flask初体验 1.安装Flask 2.创建"Hello, World" Flask应用 3.执行结果 flask是python web的轻量框架,简单的几条命令就可以创建 ...
- gorm 关系一对一,一对多,多对多查询
gorm 关系一对一,一对多,多对多查询 gorm v2版本 Belongs To mysql表 CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_IN ...
- OpenVoiceV2本地部署教程,苹果MacOs部署流程,声音响度统一,文字转语音,TTS
最近OpenVoice项目更新了V2版本,新的模型对于中文推理更加友好,音色也得到了一定的提升,本次分享一下如何在苹果的MacOs系统中本地部署OpenVoice的V2版本. 首先下载OpenVoic ...
- WebGL:使用着色器进行几何造型
前言 本文将介绍如何使用着色器来进行几何造型,说到几何图形大家一定都不陌生,比如说三角形.圆形,接触过WebGL基础使用的小伙伴一定都知道怎么去在画布上绘制一个三角形,只要传入三个顶点坐标,并选择绘图 ...
- 给公众号接入`FastWiki`智能AI知识库,让您的公众号加入智能行列
最近由于公众号用户太多,我就在思考有啥方式能给微信公众号的粉丝提供更多的更好的服务?这个时候我就想是否可以给公众号接入一下AI?让用户跟微信公众号对话,然后还能回到用户的问题,并且我提供一些资料让AI ...
- AIRIOT物联网低代码平台如何配置OPC DA驱动?
AIRIOT物联网低代码平台提供了丰富的驱动,兼容了市面上95%以上的传感器.控制器及数据采集设备等,并且在持续增加中,能够快速.便捷地实现数据采集与控制功能. AIRIOT物联网低代码平台如何配置O ...
- k8s其它学习链接
k8s弹性伸缩概念以及测试用例 https://www.cnblogs.com/jasonboren/p/11493347.html CKA看这一篇就够了 k8s官网 k8s基础之六 有状态和无状态的 ...