由于hash索引可以一次定位,不需要像树形索引那样逐层查找,因此具有极高的效率 。那为什么还需要其他的树形索引呢?
在这里愚安就不自己总结了 。引用下园子里其他大神的文章:来自 14的路 的MySQL的btree索引和hash索引的区别
(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 值相关联 。这样要定位某一条记录时就会非常麻烦,会浪费多次表数据的访问,而造成整体性能低下 。
愚安我稍作补充,讲一下HASH索引的过程,顺便解释下上面的第4,5条:
当我们为某一列或某几列建立hash索引时(目前就只有MEMORY引擎显式地支持这种索引),会在硬盘上生成类似如下的文件:
hash值存储地址
1db54bc745a177#45b5
4bca452157d476#4556,77#45cc…
…
hash值即为通过特定算法由指定列数据计算出来,磁盘地址即为所在数据行存储在硬盘上的地址(也有可能是其他存储地址,其实MEMORY会将hash表导入内存) 。
这样,当我们进行WHERE age = 18 时,会将18通过相同的算法计算出一个hash值==在hash表中找到对应的储存地址==根据存储地址取得数据 。
所以,每次查询时都要遍历hash表,直到找到对应的hash值,如(4) , 数据量大了之后,hash表也会变得庞大起来 , 性能下降,遍历耗时增加,如(5) 。
BTREE
BTREE索引就是一种将索引值按一定的算法,存入一个树形的数据结构中,相信学过数据结构的童鞋都对当初学习二叉树这种数据结构的经历记忆犹新,反正愚安我当时为了软考可是被这玩意儿好好地折腾了一番,不过那次考试好像没怎么考这个 。如二叉树一样,每次查询都是从树的入口root开始,依次遍历node,获取leaf 。
BTREE在MyISAM里的形式和Innodb稍有不同
在 Innodb里,有两种形态:一是primary key形态,其leaf node里存放的是数据,而且不仅存放了索引键的数据,还存放了其他字段的数据 。二是secondary index , 其leaf node和普通的BTREE差不多,只是还存放了指向主键的信息.
而在MyISAM里,主键和其他的并没有太大区别 。不过和Innodb不太一样的地方是在MyISAM里 , leaf node里存放的不是主键的信息 , 而是指向数据文件里的对应数据行的信息.
- mysql游标和存储过程是什么 mysql游标表名为变量
- 如何使用cmd命令行提示符登录mysql服务器 cmd中登陆mysql
- mysql怎么设置时区 mysql时间显示设置
- 招聘要精通mysql
- mysql 65535 8192 限制 mysql限制资源使用
- mysql有topn
- mysql协议包解析 mysqlicp协议
- mysql子查询和连接查询 mysql子查询插入
- Mysql使用索引查询 mysql使用round
- 云服务器游戏出现黑屏问题怎么解决? 云服务器游戏黑屏怎么办
