大家好,我是水滴~~
索引(Index)是存储引擎用于快速找到记录的一种数据结构,在 MySQL 中也被叫做键(Key)。索引对于良好的性能非常关键。尤其是当表中的数据量越来越大时,索引对性能的影响愈发重要。
索引是对查询性能优化最有效的手段,能够轻易地将查询性能提高几个数量级。索引也有多种类型,而选择“最优”的索引有时比“最好”的索引性能要好两个数量级,这通常需要重写查询。
索引有很多种类型,可以为不同的场景提供更好的性能。索引位于存储引擎层,不同存储引擎中索引的工作方式也并不一样,也不是所有存储引擎都支持所有类型的索引。即使多个存储引擎支持同一种类型的索引,其底层的实现也可能不同。
🌲 B-Tree 索引
B-Tree 索引是最常见的索引,人们谈论索引时,如果没有特别指明类型,那么一般说的是 B-Tree 索引。该索引使用的是 B-Tree 数据结构来存储数据的,对于这块知识,可以去看些数据结构相关的书籍。
大多数存储引擎都支持该索引(Archive 索引除外),但其底层实现也可能不同。例如,InnoDB 底层使用的是 B+Tree 数据结构。
🌺 使用 B-Tree 索引能够加快访问数据的速度,因为存储引擎不再需要进行全表扫描来获取需要的数据,而是从索引的根节点开始搜索。
🌹 B-Tree 索引的数据都是顺序存储的,所以很适合查询范围数据,以及对数据进行排序。
对索引有效的查询类型:
- 全值匹配
- 匹配最左前缀(组合索引)
- 匹配列前缀
- 匹配范围值
- 精确匹配某一列并范围匹配另外一列
- 只访问索引的查询
对索引无效的查询:
- 组合索引中,不按照索引的最左列开始查询,无法使用索引
- 组合索引中,不能跳过索引中的列
- 如果查询中包含某列的范围查询,则其右边所有列都无法使用索引优化查找
🌲 哈希索引
哈希索引(Hash Index)是基于哈希表实现的,只有精确匹配索引所有列的查询才有效。
🌺 存储引擎会为每一行数据的索引列计算出一个哈希码(Hash Code),并将哈希码存储在索引中,同时保存了指向该行的指针。
🌹 在 MySQL 中,只有 Memory 引擎显式地支持哈希索引,是该引擎的默认索引类型。
下面是哈希索引的一些限制:
- 索引中的数据并不是按照索引值顺序存储的,无法用于排序
- 不支持部分索引匹配查询
- 只支持等值比较查询,包括:
=
、IN()
、< = >
- 哈希冲突时,存储引擎会遍历链表中所有的行指针,逐行进行比较,直到找到所有符合条件的行;如果哈希冲突很多的话,一些索引维护操作的代码也会很高。
🌲 R-Tree 索引
R-Tree 索引也叫做空间索引,可以用于地理数据存储,目前 MyISAM 存储引擎支持该索引。
空间索引会从所有维度来索引数据,查询时,可以有效地使用任意维度来组合查询。
必须使用 MySQL 的 GIS 相关函数来维护数据。MySQL 的 GIS 支持并不完善,所以大部分人不会使用这个特性。
🌲 全文索引
全文索引是一种特殊类型的索引,它查找的是文本中的关键词,而不是直接比较索引中的值。
全文搜索和其他几类索引的匹配方式完全不一样,它更类似于搜索引擎。