本来标题是“03-MySQL优化系列之后-看透索引本质,理清B-tree和B+tree”,但是发现居然是“零推荐”,其他技术含量一般的文章,反而推荐好几千,试试换换标题看看推荐量有没有变化。
我们常常听说,要提高数据库的查询速度,就要添加索引,可是细想以下三个问题,你是否能讲清楚?
1,索引究竟是什么?
2,为什么索引可以提高查询效率?
3,既然索引这么好,那么我所有的字段都加索引好了,这样不就世界都美好了吗?
搞清楚这三个问题,基本上你对索引的认识就差不多了,阅读完本文,相信你对三个问题会非常清晰。
下面,我们一一来探索交流。
1,什么是索引
你可能常见的说法是,索引是指一本书的目录,其实这是一种近似的说法,但不是十分准确。
确切来说,索引是存储引擎用于快速找到记录的一种数据结构,是对查询性能优化最有效的手段。
2,索引到底是一种什么样的数据结构?为什么可以提高查询效率?
MySQL索引的底层数据结构,主要有两种,一种是B+tree,一种是哈希。
3,那两种数据结构,我们究竟采用哪种?
其实从定位来说,哈希完胜B+tree,因为哈希的时间复杂度是O(1),但是我们的业务系统开发场景中,更多是这样的情况,比如where id>10或者where age>18等等,大家会发现,此类方式,更多是一种范围查找,而这个就是哈希的软肋,因为哈希的前后数据并没有顺序性,是采用散列的方式进行分布,所以哈希虽好,但是根据业务系统开发的需要,我们更多采用的是B+tree的数据结构。
你可能又听说过B-tree,那么B-tree和B+tree又有什么差异?下面从B+tree的演变历史来说起
4,B+tree的演变历史
4.1 演变路线图
二叉树---》平衡二叉树---》B-tree---》B+tree
下面,我们以同样存放进1-9的数据为例,来看他们有什么差异
4.2 二叉树
二叉树,是每个节点最多有两个子节点,是一种左中右的数据结构。
存放1-9之后的结构如下:
这就是二叉树可能会存在的问题,数据一边倒,而这样就发挥不了二叉树搜索的优势,于是就有了平衡二叉树
4.3 平衡二叉树
平衡二叉树,它要求左右两个子树的高度差不能超过1,并且左右子树都是一颗平衡二叉树。
跟二叉树的最大差别在于,会通过左旋转或右旋转来保证整棵二叉树的平衡。
那么采用平衡二叉树,存储的数据结构如下:
那么平衡二叉树,看着已经挺完美了,又有什么问题?
随着数据量的增加,这颗平衡二叉树的深度也会递增,而在索引树进行查找时,随着深度的递增,跟IO交互的次数也会递增,那么性能也会下降,所以解决的办法在哪?
没错,就是在一样的数据量的情况下,减少数的深度。如何做到?
如果你想到了,真的很不错,就是将平衡二叉树变为多叉查找树,这就是我们要讲的B-tree
4.4 B-tree
采用B-tree结构,存储的数据应该是这样的,很明显,层次变少了,这样就减少了我们跟IO交互的次数
但是,这就完美了吗?
还是不够,我们再来认识B-tree的升级版B+tree
4.5 B+tree
B+tree,也称多路搜索树,他们最大的区别是,B+tree所有的数据都保存在叶子节点上,节点按照大小进行排序,结构图如下:
4.6 结论
所以,最终MySQL采用的是B+tree的数据结构,看完以上的分析,你应该已经清晰知道索引是一种什么样的数据结构,为什么可以提高搜索效率了。
4.7 衍生,聚集索引和非聚集索引
在MySQL里面,还存在,一个聚集索引和非聚集索引,他们都是指B+tree的一种具体表现,那么有什么区别?
4.7.1 聚集索引
MySQL无法主动创建聚集索引,InnoDB存储引擎会将我们的主键作为聚集索引。如果没有定义主键,则InnoDB会选择一个唯一的非空索引代替。如果没有这样的索引,则InnoDB会为该表生成一个rowid做为主键。
聚集索引的叶子节点存放表中所有的行数据信息,这样找到索引就找到了数据,而不用继续查询,这就是为什么以id主键查找数据,速度相比其他索引字段查找快的原因。
效果图如下:(偷了懒,我只是画了两个作为代表)
4.7.2 非聚集索引
我们创建的索引都属于非聚集索引,叶子节点只存放自身的键值和主键的值,叶子节点并不包含所在行的数据记录。
比如,我们为name创建了索引,那么它就是非聚集索引。如果我们的查询语句,是这样
select name from sys_user where name='feng';
那么,这个时候,使用的是覆盖索引,即索引树的数据就可以满足我们的查询需要。
而如果,这么写
select name,age,phone from sys_user where name='feng';
那么,由于非聚集索引本身没有包含行的数据,所以还需要根据自身保存的主键值,找到聚集索引树,然后再得到行数据,所以这种情况下,相比直接按主键查找效率会低。
下面,给大家留两个思考题:
1,索引的优点是提高查询效率,那么缺点是什么?
2,UUID具有唯一性的特点,那么是否合适作为主键?
希望对你有所帮助。
閱讀更多 互聯網十年老兵 的文章