Mysql索引

下面文章整理下我对mysql索引的理解

1、什么是索引

索引和表的关系可以类比于目录和书籍,它们的存在就是为了更快地检索到记录,在mysql中,索引是表的一部分,是数据记录的引用指针,只要我们愿意,我们可以设置任何一列为索引,使用的语法是index index_name(column_name1,column_name2),如果没有特别的要求,那么这个索引就是普通索引,如果使用unique index进行约束,那么这个索引就是唯一索引,如果使用primary key修饰某个字段,那么这个字段就是主键索引,如果索引包含很多列,也可以叫联合索引,上面这些都是索引的逻辑上的分类

2、索引的分类

索引可以根据数据结构,硬盘的存储方式,概念上划分为不同索引,数据结构上常见的有hash索引,b+树索引,物理存储上可以分为聚簇索引,非聚簇索引,逻辑上可以分为普通索引,唯一索引,主键索引,全文索引,联合索引。

3、索引的数据结构

常见的有hash索引和b+树索引。在不同的场景中,各有各的优势

3.1 hash索引

hash索引目前只有Memory引擎支持,hash索引的优点就是查询速度快,时间复杂度为O(1),但缺点也很明显,一是hash索引不支持范围查询,只支持等值查询,二是hash索引不支持排序操作,因为索引的大小顺序和hash后的顺序可能不太一样,三是hash索引不支持联合索引中最左匹配原则,因为hash索引,要将所有字段合并后才算hash值

3.2 B+树索引

对于B+树的理解可以看https://blog.csdn.net/jiang_wang01/article/details/113739230这位博主的文章,清晰地对比了B+树对比B树的优势,B+树的思想是二分查找,同时真正的数据存储在叶子结点,叶子结点通过链表进行串联,这样我们在范围查询的时候只要找到min和max就能定位到这段数据

3.3innodb为什么使用B+树来存储数据?

回答这个问题可以从其他数据结构的使用场景,局限性和缺点回答,比如Hash索引适合等值查询场景,不适合需要排序或者区间场景,数据索引满足等值查询和区间查询,但插入新的数据成本高,静态存储引擎可以使用,二叉树(时间复杂度高,100万行表高度为h=log100w近似于20,查询一行数据最长需要20*单位寻址时间,B树和B+树(多叉树)的不同点,B树所有节点均存储key和value两个值,而B+树仅叶子节点存储value值,这样B+树非叶子节点可以存储更多的key值信息,进一步压缩数据,提高命中率,此外叶子节点存储value可以不用中序遍历查询。

4、索引的物理存储

分为聚簇索引和非聚簇索引,根本区别是数据记录的顺序是否按照索引顺序排序,聚簇索引是唯一的,它的优点就是查询快,只要找到第一个索引的记录,其余连续性的记录在磁盘中也是连续存放的,缺点就是插入新记录慢,因为涉及到相关的数据重新排序,非聚簇索引就相反,可以存在多个,同时由于B+树的叶子节点是记录的指针,所以缺点就是有时候要有回表操作,查询时可以利用覆盖索引避免回表

5、添加索引的原则

一是查询比较少的字段不能添加索引,二是修改频繁的字段不应该添加索引,三是离散值较少的字段不能添加索引

6、最左匹配原则

最左匹配指的是联合索引时建立索引的原则,比如(name,id)会在name和(name,id)建立索引,不会对id建立索引,最左匹配原则的原理是B+树根据索引的最左的字段构建,非叶子节点根据第一个关键字进行二分,叶子节点是联合索引所有关键字的数据,所有数据根据第一个关键字排序,第二、三、四无序,当第一个第一关键字相同时,第二个关键字就有序了啊,所以当查询的时候遇到between和大于小于,后面的索引就失效了,因为后面就不是有序的了,此外,因为mysql有优化器,查询条件会自动排成联合索引的顺序

7、联合索引的好处

一是联合索引减少创建索引的开销,创建一个索引等于创建n个索引,二是减少检索量,第一个索引可以排除一些数据,第二个索引可以排除剩下的一些数据,三是可以利用覆盖索引,减少回表

9、索引失效的场景

思考B+树和联合索引以及最左匹配的原理能得到不遵守最左匹配原则会失效,between和大于小于右边会失效,%在最开头会失效
二是索引失效考虑的是检索成本,比如is null,is not null,!=,<>有时会走,有时不会走,sql优化器在使用二级索引的时候会预估记录的条数,如果比例过大,那么优化器就偏向直接走聚簇索引

10、索引下推

理解索引下推首先要明白Mysql的架构,简单来说分为了三层,第一层client,第二层server,第三层存储引擎。索引下推指得就是将服务层负责的事情交给下层存储引擎去干。
如果没有索引下推,mysql的查询:
1.存储引擎根据索引直接或者间接获得主键值,定位并完整读取整行数据
2. 存储引擎把获取的记录交给Server层去检测记录是否满足WHERE条件
这样存在一个问题就是有些数据并不需要进行回表定位,这部分数据也消耗了部分性能,索引下推就是解决这个问题的。
有了索引下推,mysql的查询是这样的:
1.存储引擎获得索引记录,根据索引的where条件过滤掉不满足的索引,根据这些满足条件的索引去获取主键,然后进行回表定位读取完整行数据
2.存储引擎把记录交给Server层,Server层检测该记录是否满足WHERE条件的其余部分。
参考网络上的一篇图片

11、参考文章

1.组合索引和最左匹配原则
2.%导致索引失效情况
3.索引下推

posted @ 2022-11-07 02:00  不要给我歪!  阅读(45)  评论(0编辑  收藏  举报