Mysql索引 索引有什么用

推荐学习

  • 周一福利到!献上“独家全新”MySQL进阶套餐,简直就是血赚
  • “吃”完这本Java性能调优实战,MySQL+JVM+Tomcat等问题一键全消
前言相信每个IT界大佬,简历上少不了Mysql索引这个关键字,但如果被问起来,你能说出多少干货呢?先看下面几个问题测试一下吧:
  • 索引是怎么提高查询效率的?可以为了提高查询效率增加索引么?
  • mysql索引系统采用的数据结构是什么?
  • 为什么要使用B+树?
  • 聚集索引相对于非聚集索引的区别?
  • 什么是回表?
  • 什么是索引覆盖?
  • 什么是最左匹配原则?
  • 索引失效场景有哪些,如何避免?
这些问题说不明白?不要慌!请带着问题向下看 。
Mysql索引 索引有什么用

文章插图
1 索引原理探究什么是数据库索引?先来个官方一些的定义吧 。
在关系数据库中,索引是一种单独的、物理的数对数据库表中一列或多列的值进行排序的一种存储结构,它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单 。
这段话有点绕,其实把索引理解为图书目录,就非常好理解了 。
如果我们想在图书中查找特定内容,在没有目录的情况下只能逐页翻找 。与此类似,当执行下面这样一条SQL语句时,假如没有索引,数据库如何查找到相对应的记录呢?
SELECT * FROM student WHERE name='叶良辰'
搜索引擎只能扫描整个表的每一行,并依次对比判断name的值是否等于“叶良辰” 。我们知道,单纯的内存运算是很快的,但从磁盘中取数据到内存中是相对慢的,当表中有大量数据时,内存与磁盘交互次数大大增加,这就导致了查询效率低下 。
1.1 B树与B+树相对于cpu和内存操作,磁盘IO开销很大,非常容易成为系统的性能瓶颈,因此计算机操作系统做了一些优化:
当一次IO时,将相邻的数据也都读取到内存缓冲区内,而不是仅仅读取当前磁盘地址的数据 。因为局部预读性原理告诉我们,当计算机访问一个地址的数据的时候,与其相邻的数据也会很快被访问到 。每一次IO读取的数据我们称之为一页(page) 。具体一页有多大数据跟操作系统有关,一般为4k或8k,也就是我们读取一页内的数据时候,实际上才发生了一次IO,这个理论对于索引的数据结构设计非常有帮助 。
为什么索引能提升数据库查询效率呢?根本原因就在于索引减少了查询过程中的IO次数 。那么它是如何做到的呢?使用B+树 。下面先简单了解一下B树和B+树 。
B树,即平衡多路查找树(B-Tree),是为磁盘等外存储设备设计的一种平衡查找树 。
B树简略示意图:
Mysql索引 索引有什么用

文章插图

观察上图可见B树的两个特点:
  1. 树内的每个节点都存储数据
  2. 叶子节点之间无指针连接
B+树简略示意图:
Mysql索引 索引有什么用

文章插图

再看B+树相对于B树的两个特点:
  1. 数据只出现在叶子节点
  2. 所有叶子节点增加了一个链指针
叶子结点是离散数学中的概念 。一棵树当中没有子结点(即度为0)的结点称为叶子结点,简称“叶子” 。叶子是指出度为0的结点,又称为终端结点 。
但是,为什么是B+树而不是B树呢?原因有两点:
  1. B树每个节点中不仅包含数据的key值,还有data值 。而每一个页的存储空间是有限的,如果data数据较大时将会导致每个节点能存储的key的数量很小,要保存同样多的key,就需要增加树的高度 。树的高度每增加一层,查询时的磁盘I/O次数就增加一次,进而影响查询效率 。而在B+Tree中,所有数据记录节点都是按照键值大小顺序存放在同一层的叶子节点上,而非叶子节点上只存储key值信息,这样可以大大加大每个节点存储的key值数量,降低B+树的高度 。
  2. B+树的叶子节点上有指针进行相连,因此在做数据遍历的时候,只需要对叶子节点进行遍历即可,这个特性使得B+树非常适合做范围查询 。
1.2 聚簇索引与非聚簇索引首先,为了方便理解,我们先了解一下聚集索引(clustered index)和非聚集索引(secondary index,也称辅助索引或普通索引) 。这两种索引是按存储方式进行区分的 。
聚集索引(clustered)也称聚簇索引,这种索引中,数据库表行中数据的物理顺序与键值的逻辑(索引)顺序相同 。一个表的物理顺序只有一种情况,因此对应的聚集索引只能有一个 。如果某索引不是聚集索引,则表中的行物理顺序与索引顺序不匹配,与非聚集索引相比,聚集索引有着更快的检索速度 。