Innodb索引数据结构灵魂拷问

发布时间 2023-11-13 10:41:29作者: beeboo1

问题1:Innodb数据结构为什么要用B+树,如果比红黑树要好的话,为什么Java HashMap不用B+树而用红黑树?

如果数据全在内存的话,红黑树要比B+树好,查找次数比B+树要少很多,B+树适合磁盘IO,因为一次IO可以加载很多节点数据,查找次数虽多但IO次数少。红黑树是瘦长的,B+树是矮胖的。IO的次数取决于树的高度。

问题2:为什么IO的次数要取决于树的高度,我一次IO多加载几层不一样可以少些IO吗,必须得一层层加载到内存?

因为Innodb是把一页的数据放在同一高度的,一次IO加载一页,只能一层层加载,就是这么设计的,然后在这个设计基础上,当然是每层的数据填满页,即把树变胖,高度变矮IO次数会更少。

问题3:为什么不用B树?

因为B树的非叶子节点也不光有索引的Key还有Data,那一次IO加载的一页数据16K中的索引Key就要少很多,那这势必要更多次IO才能加载出所需的索引Key了。所以应该把非叶子节点的Data去掉,把空间让给索引Key。

问题4:为什么默认不用Hash索引?

仅支持=,in查询。
索引冲突多的话,相同hash的数据是链表的线性结构,查找起来也不快。

问题5:为什么建议InnoDB表必须建主键,并且推荐使用整型的自增主键?

1.为什么要有主键?
如果不建主键,MySQL会帮我们选一个非空唯一列来当主键组织聚簇索引,如果没有则建一个隐藏列rowid当主键。这就强加了一些工作给MySQL,没必要。并且如果选择出来的非整型自增字段作主键性能也不好。

2.为什么要整型?
查找时比较大小更快

3.为什么要自增?
避免插入时增加维护聚簇索引的开销。
如果使用自增主键:
那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,主键的顺序按照数据记录的插入顺序排列,自动有序。当一页写满,就会自动开辟一个新的页。
如果使用非自增主键(如身份证号或学号等):
由于每次插入主键的值近似于随机,因此每次新纪录都要被插到现有索引页得中间某个位置,此时MySQL不得不为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这增加了很多开销,同时频繁的移动、分页操作造成了大量的碎片,得到了不够紧凑的索引结构,后续不得不通过OPTIMIZE TABLE来重建表并优化填充页面。

Refrence: https://blog.xxmoon.com