BTREE索引和HASH索引,聚集索引和非聚集索引

https://www.jianshu.com/p/76530afa13cb

https://blog.csdn.net/yifanSJ/article/details/79220044

BTREE索引和HASH索引

1、不同引擎的默认索引

不同的引擎对于索引有不同的支持:Innodb和MyISAM默认的索引是Btree索引;而Mermory默认的索引是Hash索引。

 

2、Hash索引

所谓Hash索引,当我们要给某张表某列增加索引时,将这张表的这一列进行哈希算法计算,得到哈希值,排序在哈希数组上。所以Hash索引可以一次定位,其效率很高,而Btree索引需要经过多次的磁盘IO,但是innodb和myisam之所以没有采用它,是因为它存在着好多缺点:

(1)Hash 索引仅仅能满足"=","IN"和"<=>"查询,不能使用范围查询。

由于 Hash 索引比较的是进行 Hash 运算之后的 Hash 值,所以它只能用于等值的过滤,不能用于基于范围的过滤,因为经过相应的 Hash 算法处理之后的 Hash 值的大小关系,并不能保证和Hash运算前完全一样。

(2)Hash 索引无法被用来避免数据的排序操作。

由于 Hash 索引中存放的是经过 Hash 计算之后的 Hash 值,而且Hash值的大小关系并不一定和 Hash 运算前的键值完全一样,所以数据库无法利用索引的数据来避免任何排序运算;

(3)Hash 索引不能利用部分索引键查询。

对于组合索引,Hash 索引在计算 Hash 值的时候是组合索引键合并后再一起计算 Hash 值,而不是单独计算 Hash 值,所以通过组合索引的前面一个或几个索引键进行查询的时候,Hash 索引也无法被利用。

(4)Hash 索引在任何时候都不能避免表扫描。

前面已经知道,Hash 索引是将索引键通过 Hash 运算之后,将 Hash运算结果的 Hash 值和所对应的行指针信息存放于一个 Hash 表中,由于不同索引键存在相同 Hash 值,所以即使取满足某个 Hash 键值的数据的记录条数,也无法从 Hash 索引中直接完成查询,还是要通过访问表中的实际数据进行相应的比较,并得到相应的结果。

(5)Hash 索引遇到大量Hash值相等的情况后性能并不一定就会比B-Tree索引高。

对于选择性比较低的索引键,如果创建 Hash 索引,那么将会存在大量记录指针信息存于同一个 Hash 值相关联。这样要定位某一条记录时就会非常麻烦,会浪费多次表数据的访问,而造成整体性能低下。

 

3、Btree索引

至于Btree索引,它是以B+树为存储结构实现的。

但是Btree索引的存储结构在Innodb和MyISAM中有很大区别。

MyISAM中数据文件和索引文件是分开的,索引文件保存的是数据在数据文件的地址。

Innodb的索引文件就是数据文件,相当于是重新建立了一个有索引顺序的数据文件。另外在Innodb中,辅助索引的叶子节点存储的是主键信息,然后根据主键信息到主索引中定位表中的数据。因此主键不宜用过长的字段,在Innodb中尽量使用自增的主键,这样每次增加数据时只需要在后面添加即可,非单调的主键在插入时会需要维持B+tree特性而进行分裂调整,重新建立索引,十分低效。

因此MyISAM的索引方式也称为非聚集,Innodb的索引方式称为聚集索引。

 

4、下面需要说明一下聚集索引和非聚集索引的概念

聚集索引

1.当你定义一个主键时,InnnodDB存储引擎则把它当做聚集索引

2.如果你没有定义一个主键,则InnoDB定位到第一个唯一索引,且该索引的所有列值均非空的,则将其当做聚集索引。

3如果表没有主键或合适的唯一索引INNODB会产生一个隐藏的行ID值6字节的行ID聚集索引,

补充:由于实际的数据页只能按照一颗B+树进行排序,因此每张表只能有一个聚集索引,聚集索引对于主键的排序和范围查找非常有利,

非聚集索引

一个表中的所有索引除了聚集索引,其他的都是非聚集索引(secondary index)

辅助索引,其叶子节点并不包含行记录的全部数据,叶子结点除了包含键值以外,每个叶子结点中的索引行还包含了一个书签,该书签用来告诉存储引擎可以在哪找到相应的数据行,由于innodb引擎表是索引组织表,因此innodb存储引擎的辅助索引的书签就是相应行数据的聚集索引键,即主键信息。

 

5、 Btree索引中的最左匹配原则

Btree是按照从左到右的顺序来建立搜索树。比如索引是(name,age,sex),相当于是建立了单列索引(name)、组合索引(name,age)和组合索引(name,age,sex)。假如搜索age=? and sex =?或者name=? and sex=?的话都是利用不到这个索引的。

 

6、 索引的index类型和ref类型

http://blog.csdn.net/qq_24690761/article/details/52787897

在使用EXPLAIN分析查询语句的时候会发现type有index类型和ref类型。

index类型表示是全表扫描该索引。只要是索引,或者某个复合索引的一部分,mysql都可能会采用index类型的方式扫描。但是因为是全表从头到尾扫描,因此效率并不高。

ref类型表示能够利用到建立好的索引,快速定位到索引的位置,而不是全表扫描。要利用到这种索引就要符合最左匹配原则。

 

7、建立索引的规则

1、利用最左前缀:Mysql会一直向右查找直到遇到范围操作(>,<,like、between)就停止匹配。比如a=1 and b=2 and c>3 and d=6;此时如果建立了(a,b,c,d)索引,那么后面的d索引是完全没有用到,当换成了(a,b,d,c)就可以用到。

2、不能过度索引:在修改表内容的时候,索引必须更新或者重构,所以索引过多时,会消耗更多的时间。

3、尽量扩展索引而不要新建索引。

4、最适合的索引的列是出现在where子句中的列或连接子句中指定的列。

5、不同值较少的列不必要建立索引(性别)。

你可能感兴趣的:(Mysql)