带着问题看文章
- 索引数据结构红黑树、Hash、B+树是什么?
- 千万级数据表如何用B+树索引快速查找?
- 聚集索引、聚族索引、稀疏索引到底是什么?
- 为什么DBA总推荐使用自增主键做索引?
- 联合索引底层的数据又是怎么样的?
- Mysql最左前缀优化原则是怎么回事?
一、索引结构
前言
索引是帮助MySQL高效获取数据的排好序的数据结构。
1、红黑树
2、Hash
- 对索引的key进行一次hash计算就可以定位出数据存储的位置
- 很多时候Hash索引要比B+ 树索引更高效
- 仅能满足 “=”,“IN”,不支持范围查询(工作中大部分都不会使用Hash的原因)
- hash冲突问题
3、B树/B+树
(1)B树
- 叶节点具有相同的深度,叶节点的指针为空
- 所有索引元素不重复
- 节点中的数据索引从左到右递增排列
(2)B+树
- 非叶子节点不存储data,只存储索引(冗余),可以放更多的索引
- 叶子节点包含所有索引字段
- 叶子节点用指针连接,提高区间访问的性能
面试题:为什么Mysql选用了B+树而不是B树?
存储同样数据的时候,B+树的层数小于B树,所以有更好的查找性能。
因为一个节点最多存放16kb大小的数据,而带B树每一层每个节点都会带有数据,所以节点变大了每一层存的数据就变少了,层数就变大了。而B+树只有前两层都是冗余索引,因此可以带有更多的节点,层数就小了。
二、InnoDB存储引擎
1、索引类型
(1)聚集索引
是指索引和数据放在同一个文件夹下。
InnoDB是聚集索引
(2)非聚集索引
是指索引和数据放在不同文件夹下。
MyISAM索引文件和数据文件是分离的(非聚集)
2、联合索引
(1)底层存储结构
(2)索引最左前缀原理
1、Select * from tableName Where name = "Bill" and age = 31;
2、Select * from tableName Where age = 30 AND position = 'dev';
3、Select * from tableName Where position = 'manger';
上面三条sql语句中只有第一条会走索引 在(1)的图中可以看到属性的顺序是name、age、position,名字是排好序的,但是age和position不一定是排好序的,所以才有最左前缀原理。
面试题:聚集索引和非聚集索引哪个更快?不考虑其他因素
答:“聚集索引”(非聚集索引还要跨文件查找数据)
面试题:为什么建议InnoDB表必须建主键,并且推荐使用整型的自增主键?
InnoDB可以用自增主键来当索引维护这张表(具体参考上面的B+树)。
如果没有主键,那InnoDB会找到一列完全不相同的数据来当索引。
如果还是没有找到,那Mysql会维护一个虚拟列,该列内的id完全不相同,然后使用这个虚拟列rowid来维护这张表。数据库资源是宝贵的,没必要让Mysql帮我们做这些事情。
看到这里是不是认为只需要主键就可以了~
使用主键,更重要的是使用自增的索引,因为B+树底层是排好序的,低层的节点有双向指针,如果不自增的,Mysql可能还需要去帮你平衡这颗树。
面试题:为什么非主键索引结构叶子节点存储的是主键值(rowid)?
使用某一列来当索引,底层节点存储的是主键值(rowid),将来的查询会有回表的操作,这里主要是一致性和节省存储空间。