MySQL btree索引与hash索引方式的区别
时间:2015-09-01 阅读:次 QQ群:182913345
Hash 索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 B-Tree 索引。但是现实中都很少用 Hash 索引,用 B-Tree 索引比hash索引多得多。可以这样理解,BTREE索引是一种B树结构索引,里面的数据根据大小或者其它原因进行了各种编排,查询时将数据与里面各节点的数据进行对比以快速找到目标。而hash索引是一种集合索引,它对要查询的数据都已经进行了hash处理,并且把处理的结果与存储的位置对应了起来,这样当你查询某一个值时,它能根据这个值计算出一个与存储位置相关的结果,从而实现快速命中目标。所以既然如此hash在命中高的同时也有很重要的劣势。
1、Hash 索引仅仅能满足"=","IN"和"<=>"查询,不能使用范围查询,也不能使用匹配%,搜索查询,也不能进行排序操作
由于Hash索引比较的是进行 Hash 运算之后的 Hash 值,所以它只能用于等值的过滤,对于像where id>5或者where title like '%abc%'之类的查询无能为力。而也正因为这样,对hash索引也不能进行排序。而这些都是很多数据读取操作中经常要使用的功能,所以多数索引仍会使用B-TREE索引。
2、联合索引里无法使用Hash索引
对于联合索引,Hash 索引在计算 Hash 值的时候是组合索引键合并后再一起计算 Hash 值,而不是单独计算 Hash 值,所以通过组合索引的前面一个或几个索引键进行查询的时候,Hash 索引也无法被利用。
3、Hash 索引遇到大量Hash值相等的情况后性能并不一定就会比B-Tree索引高
对于数据重复性比较高的列,如果创建 Hash 索引,那么将会存在大量记录指针信息存于同一个 Hash 值相关联。比如对用户的学历、职称、性别进行索引,这些字段值比较固定,hash索引时要定位某一条记录时就会非常麻烦,会浪费多次表数据的访问,而造成整体性能低下。hash表更适合于唯一性高但又不要求进行排序或者取范围时用的索引,这点让我想起来REDIS里的hash结构,你扔给他一个hash,键名为用户名,键值为用户的数据json结构,这个就非常适合使用hash,因为hash会大大提高命中,所以REDIS里能有这么快的速度。
我看到网上有上有很多被转载的文件上都写有一点:Hash 索引在任何时候都不能避免表扫描(Hash 索引是将索引键通过 Hash 运算之后,将 Hash运算结果的 Hash 值和所对应的行指针信息存放于一个 Hash 表中,由于不同索引键存在相同 Hash 值,所以即使取满足某个 Hash 键值的数据的记录条数,也无法从 Hash 索引中直接完成查询,还是要通过访问表中的实际数据进行相应的比较,并得到相应的结果)。我觉得HASH之所以快就是采用了hash值去查找数据的方式,即便它进行所谓的“表扫描”,也是一很优化的表扫描,不然hash的查询效率如何远高于B-TREE索引。