首先Mysql中索引是使用了B+Tree的结构,具体数据结构可以看这里。
聚簇索引: 其叶子节点就是对应了物理上的行,并且其保证了叶子结点的顺序与物理位置一致。 这个特性决定了其不适合使用在随机字符串类似的字段上,因为有可能会造成大量的数据移动。 还决定了其能够很好的利用数据库预读以及页读的功能很快的查找范围内的数据。
非聚簇索引: 其叶子节点存储了列值及到行的指针。因此其顺序跟物理顺序无关,插入的效率要高很多,因为仅仅是移动节点的指针不会涉及数据移动。
覆盖索引: 当要提取的数据在叶子节点中就能够获取,而不用去查找数据块时就叫做覆盖索引。因为索引中的数据时顺序的,并且空间比较小,因此会带来比较高的性能。
使用取舍:
行为 | 聚簇索引 | 非聚簇索引 |
---|---|---|
列常被group by | 可以 | 可以 |
列经常被between等范围查询 | 效率高 | 效率低 |
频繁更新的列 | 效率低 | 效率高 |
列常被order by | 可以 | 可以 |
获取大于20%的数据 | 不可 | 不可 |
此外,在插入非常频繁的场景下,聚簇索引因为插入的热点都是在最尾端,因此有可能会有性能问题,可以通过配置innodb_autoinc_lock_mode 来配置这种情况下的处理方式,表锁还是预读预置一些值给语句使用
哈希索引使用了哈希算法。其具有如下的特性:
总结一下: