- 为什么 MySQL 选择使用 B+ 树作为索引结构?(中等)
- MySQL 索引的最左前缀匹配原则是什么?(简单)
- MySQL 三层 B+ 树能存多少数据?(中等)
今日面试题
1. MySQL 索引的最左前缀匹配原则是什么?
mysql的联合索引,从最左侧开始查询,若是没查询最左侧,就不能触发联合索引,从左到右依次排序。
在mysql5.6加入索引下推优化,只要查询了最左侧的值,中间的值不查,也可以走索引。必须遇到=、或者<=、>=才能进行索引查询,纯范围不行,范围的查不了联合索引。所以高频和区分度高的放左边。
mysql8进行skipscan优化,当索引很小,且查询的是索引有的列可以跳过最左前缀匹配原则,官方文档要求其中基数很低,所以适用范围小。
即便写反了,mysql比较聪明会自动把该放前面的先查询。
2. 为什么 MySQL 选择使用 B+ 树作为索引结构?
磁盘IO次数少,对硬盘友好。而索引本身目的就是为了减少磁盘访问次数。
B+树比较矮,查硬盘次数最少,效率最高。因为其只存key和指针,缓存效率高,命中高。叶子节点有双向链表,顺序IO快。
红黑树、AVL树比较高,最坏情况几十次查询,所以内存可以用红黑树,而硬盘效率问题不能用。b+树只存key和指针,存的效率还是最高的,而b树里面有数据,就不如b+树了。b树会在非叶子节点查到直接返回,看起来快,但是范围和排序需求不能实现。
INNODB的b+树用的是昨天学的聚簇索引和二级索引。一个是按主键排列,一个是按主键和值排列,没主键就自己生成一串字符。二级索引会二次查表。
数据插入页满了,会触发页分裂,利用率低会页合并,都会影响性能。
主键短一些key就可以存的少点,就能树矮减少IO,二级索引也会更大。
3. MySQL 三层 B+ 树能存多少数据?
16kb(innodb默认页大小)* 1024b / 14(主键bigint 8字节 + 指针6字节),一个非叶子节点就是1170个,一个节点数据1kb,那就是16/1=16条(如果主键换UUID 36字节,就会到240w条)。
所以总记录为 1170 * 1170 * 16 = 2190w,但是因为数据有所波动,所以以实际为准。
b+树压的矮胖,让IO读取更少,每个节点存的东西更多,3-4次IO最多,就可以查到数据。
页大小为16kb可以防止占用过大,颗粒度放大。随机读写性能好。除非都是宽数据,不然不用改。
非叶子节点不存数据可以让树高变低,效率提高。
当慢查询增多才要分表分库,能不分就不分,容易复杂化。