MySql数据库索引
Posted yimengyizhen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySql数据库索引相关的知识,希望对你有一定的参考价值。
HASH索引
对于每一行数据,对应索引列都会有一个不同的哈希码,并且将哈希码和指向数据行的指针维护到哈希表中。
特点
- 无法用于排序 (因为哈希索引数据不是按照索引值顺序存储的)
- 不支持部分索引列查找(如果在name和age两列上建立索引,如果查询只有name,则无法使用索引。)
- 不支持范围查询(比如where age>20)
- 可能会出现hash冲突(如果多个数据列对应的hash值匹配到了哈希表中的同一节点上,那么会去遍历这个节点上所有的值,直到找出匹配或者无匹配值,这样就会严重影响查询效率)
- 在InnoDB引擎中的哈希索引由引擎自动优化创建,我们无法手动创建哈希索引(高性能mysql中有这么一个例子 如果需要存储大量url,并且需要进行查找,使用BTREE的话路径会很长,所以可以使用CRC32对url做哈希,这样就可以通过hash去匹配主键,再找到对应的记录)
BTREE索引
使用B-Tree数据结构来存储数据。
特点
- 顺序存储,适合查找范围数据
- 支持部分索引列查找,但是只支持以下类型
(1)全值匹配:即和索引中所有列进行匹配。
(2)匹配最左前缀 如之前提到的只索引name,并且不能跳过索引中的列,如有索引(name,age),则不能直接匹配age。
(3)匹配列前缀:即匹配某一列的开头部分,比如name中以zhang开头的。
(4)匹配范围值:即匹配某一列的范围。
(5)精确匹配某一列并模糊匹配另外一列,比如 有索引(name,age,sex)有查询条件 where name =‘zhangsan‘ and age >20 , 这样sex就无法使用索引优化查找)
如何使用索引?
- 索引列不能是表达式的一部分
- 有时候需要索引很长的字符,如前面提到的url,除了模拟哈希,也可以索引开始的部分字符,这样可以节约索引空间,提高效率,但是也会降低索引的选择性,所以在考虑前缀时应该使前缀的选择性接近于索引整个列(但是也需要考虑数据分布不均匀的情况)。
索引的选择性:不重复的索引值和数据表记录总数的比值,索引的选择性越高查询效率越高,就可以在查询时过滤掉更多的行
- 通常情况下,尽可能的扩展索引,而不是建立新的索引
- 选择选择性高的列放在索引的前面。
聚簇索引
聚簇索引不是单独的索引类型,而是一种数据存储方式。节点页中包含索引列,在叶子页中包含所有数据行(比如id存储在节点页中,该id对应的行数据存储在叶子页中)。
特点
- 数据访问快(因为索引和数据保存在一个树中)
- 使用覆盖索引可以直接使用节点页中的主键值
- 最好避免随机的聚簇索引,按照主键的顺序插入是最快的方式(比如auto_increment),否则会出现页分裂和碎片,严重影响性能(比如uuid)
- 二级索引访问需要两次查找(先查找对应数据的主键id,再通过id查找对应数据行)
覆盖索引
一个索引包含所有需要查询字段的值。
特点
- 避免回表(如前面所说,二级索引访问数据需先得到id,然后通过id找到对应数据行,这种现象称之为“回表”,可以通过覆盖索引的方式避免回表)
- 只需读取索引,减少数据的访问。
参考资料:高性能MySql
以上是关于MySql数据库索引的主要内容,如果未能解决你的问题,请参考以下文章