一、首先我们的一个表的数据在磁盘上由于插入顺序的原因肯定不是顺序存放,如果按照表字段内容顺序查找,如果一个500万条数据的表,要找的刚好是第500万个值,则需要与磁盘做500万次IO,效率低下

二、为什么不用二叉树,如果将一个乱序的数据放入二叉树中,效率会高,但是如果数据是有顺序的,比如1、2、3、4、5,则二叉树将会编程一个链表的样式,失去了二叉树的优势

三、为什么不用红黑树,红黑树也叫二叉平衡树,红黑树可以有效解决掉顺序数据一次放入二叉树而导致的形成链表的结果,但是红黑树一个节点只能存储一个数据,就导致如果是大量的数据,红黑树的高度就不可控,如果一个红黑树是20的高度,要查询的数据在叶子结点,则表示需要需磁盘20次IO,效率还是不高

四、为什么不用B树,B树比红黑树的优势是,B树是一个节点上存储多个数据,比如磁盘的一页数据,这样的横向扩展,相同的数据量就可以比红黑树减少更多的高度,从而减少了磁盘的IO次数,下面开始对比B树和B+树,就会发现B+树在查询数据方面要比B树有很多便捷的地方

B树:data为数据的磁盘地址,还可能是整条列的数据

1、数据是分散在每个结点上的,所有结点元素不重复,

2、结点元素从左到右递增

3、叶子结点具有相同的深度,叶子结点的指针为空

为什么用mysql不用es mysql为什么不用b树_mysql

B+树:data为数据的磁盘地址,还可能是整条列的数据

1、叶子结点包含了所有的索引字段,以及数据的磁盘地址,而非叶子结点不在存储data数据,作用只是便于查找的冗余索引

2、非叶子结点是从子结点选取一页的开头来作为自己的值,指针为子结点那页的地址

3、每一个结点里的值都是排好序的

4、叶子结点之间还有指针可以互相访问,这样方便了范围查找,比如where col > 10,这是mysql对B+的变种,也是对比B树的一个优势

5、由于data可能会很大,非叶子结点在不存储data后,非叶子可以存储的元素则会变多,还可以降低树的高度,提高了查询的效率,这是与B树对比,B+树的一个优势

(注:内存里二分查找数据的范围要比一个IO快的多,所以一次IO加载更多的数据,可以提高查询的效率,一页为多大也可以sql查询与设置)

 

为什么用mysql不用es mysql为什么不用b树_mysql_02

查询演示:如果查询值为30的数,查找顺序为:

1、先将根结点15-56-77加载到内存,(根结点常驻内存)使用二分查找,可以查找到30所在的位置,也就是15到56之间,也就可以得到15那页子结点的磁盘地址

2、将子结点15-20-49加载到内存,二分查找30所在的位置为20到49之前,也就同时可以获得20那页子结点所在的磁盘地址

3、再将叶子结点20-30的加载到内存,再查询到30数据的data

五、聚簇索引和非聚簇索引解释:

1、MyISAM和InnoDB存储引擎是只的数据库表,一个数据库里可以给不同的表指明不同的存储引擎

2、MyISAM存储引擎的表会生成3个磁盘文件,.frm(表结构)、.MYD(表数据)、.MYI(表索引文件),MyISAM存储引擎是非聚簇索引,它将表数据与表索引文件分开存储,如图展示,绿色的索引部分存储在.MYI文件里,蓝色的数据部分存储在.MYD文件里,例如在.MYI文件里查询到了30值的data为0x6A,则会通过这个磁盘地址去.MYD文件里查询该行的数据,MyISAM的一级索引和二级索引结构一致

为什么用mysql不用es mysql为什么不用b树_mysql_03

3、InnoDB存储引擎会生成2个磁盘文件,.frm(表结构)、.idb(表数据加索引),InnoDB存储引擎是聚簇索引,它表数据与表索引一起存储,在B+树的叶子结点里不再存储的是该行的磁盘空间位置,而是该行的全部列数据,这样就可以不再一次寻址(回表),由于它表数据与表索引一起存储,所以就必须有一个主键索引来组建我们整张表,主键所以建议使用整型递增的类型,(整型是因为整型在值对比的过程中要快很多,且整型占用空间小,一页能存储的数据就会比较多,索引整体也会变小,自增是因为递增的值插入B+树的可以直接尾部加结点就好,如果是中间值就可能还需要拆分结点插入,毕竟B+树本身维护的就是递增的顺序)如果没有自主定义一个主键,mysql就会从现有字段里挑选一个不会有重复值的列,如果还发现没有,就会建一个隐藏列来组建主键索引,所以,最好还是自主定义主键

为什么用mysql不用es mysql为什么不用b树_为什么用mysql不用es_04

InnoDB的二级索引结构与主键索引不太一致,二级索引也是非聚集索引

为什么用mysql不用es mysql为什么不用b树_为什么用mysql不用es_05

 可以看到二级索引的data存储的是主键索引的那个值(回表),这样的好处,一是可以节约空间,我们并不需要每个索引的叶子结点都存错了全部的数据,二是为了保证一致性,如果字段值存储多份,就需要保证插入更新的一直性,增加复杂度

六、联合索引

一般不建议建多个单值索引,而是推荐多个字段一起建一个组合索引,节省空间

 图例是一个联合主键索引,也可以建立联合的二级索引

原理就是先用name排序,再用age排,再用position排,这里就是有了最左匹配原则,where条件可以name = ""、name = "" and age = ""和name = "" and age = "" and position = "" 都可以使用该联合索引查找

为什么用mysql不用es mysql为什么不用b树_结点_06

 

七、mysql的Hash索引

mysql的Hash索引就比较容易理解,给索引字段的每个值都进行一次Hash计算,维护了一个类似数组加链表的模式,链表是用来存储Hash碰撞的值。Hash索引在等值查询上,比如“=”或者“IN”上,最高效率可以只用一次的磁盘交互即可取值,比B+树需要多次对比要快的多,但是由于Hash的性质导致不支持范围查询。

为什么用mysql不用es mysql为什么不用b树_B+树_07