MySql数据库索引

HASH索引

对于每一行数据,对应索引列都会有一个不同的哈希码,并且将哈希码和指向数据行的指针维护到哈希表中。

特点

  1. 无法用于排序 (因为哈希索引数据不是按照索引值顺序存储的)
  2. 不支持部分索引列查找(如果在name和age两列上建立索引,如果查询只有name,则无法使用索引。)
  3. 不支持范围查询(比如where age>20)
  4. 可能会出现hash冲突(如果多个数据列对应的hash值匹配到了哈希表中的同一节点上,那么会去遍历这个节点上所有的值,直到找出匹配或者无匹配值,这样就会严重影响查询效率)
  5. 在InnoDB引擎中的哈希索引由引擎自动优化创建,我们无法手动创建哈希索引(高性能Mysql中有这么一个例子 如果需要存储大量url,并且需要进行查找,使用BTREE的话路径会很长,所以可以使用CRC32对url做哈希,这样就可以通过hash去匹配主键,再找到对应的记录)

BTREE索引

使用B-Tree数据结构来存储数据。

特点

  1. 顺序存储,适合查找范围数据
  2. 支持部分索引列查找,但是只支持以下类型

(1)全值匹配:即和索引中所有列进行匹配。

(2)匹配最左前缀 如之前提到的只索引name,并且不能跳过索引中的列,如有索引(name,age),则不能直接匹配age。

(3)匹配列前缀:即匹配某一列的开头部分,比如name中以zhang开头的。

(4)匹配范围值:即匹配某一列的范围。

(5)精确匹配某一列并模糊匹配另外一列,比如 有索引(name,age,sex)有查询条件 where name ='zhangsan' and age >20 , 这样sex就无法使用索引优化查找)

如何使用索引?

  1. 索引列不能是表达式的一部分
  2. 有时候需要索引很长的字符,如前面提到的url,除了模拟哈希,也可以索引开始的部分字符,这样可以节约索引空间,提高效率,但是也会降低索引的选择性,所以在考虑前缀时应该使前缀的选择性接近于索引整个列(但是也需要考虑数据分布不均匀的情况)。

索引的选择性:不重复的索引值和数据表记录总数的比值,索引的选择性越高查询效率越高,就可以在查询时过滤掉更多的行

  1. 通常情况下,尽可能的扩展索引,而不是建立新的索引
  2. 选择选择性高的列放在索引的前面。

聚簇索引

聚簇索引不是单独的索引类型,而是一种数据存储方式。节点页中包含索引列,在叶子页中包含所有数据行(比如id存储在节点页中,该id对应的行数据存储在叶子页中)。

特点

  1. 数据访问快(因为索引和数据保存在一个树中)
  2. 使用覆盖索引可以直接使用节点页中的主键值
  3. 最好避免随机的聚簇索引,按照主键的顺序插入是最快的方式(比如auto_increment),否则会出现页分裂和碎片,严重影响性能(比如uuid)
  4. 二级索引访问需要两次查找(先查找对应数据的主键id,再通过id查找对应数据行)

覆盖索引

一个索引包含所有需要查询字段的值。

特点

  1. 避免回表(如前面所说,二级索引访问数据需先得到id,然后通过id找到对应数据行,这种现象称之为“回表”,可以通过覆盖索引的方式避免回表)
  2. 只需读取索引,减少数据的访问。
参考资料:高性能MySql
posted @ 2020-06-30 19:02  亦梦亦真  阅读(144)  评论(0编辑  收藏  举报