MySQL InnoDB&MyISAM 反对 Hash 么
咱们在应用 MySQL 的时候, 对于索引的数据类型, 应用的最多的就是 HASH 和 BTREE. 很多开发人员很有教训的会在创立某些字段的索引的时候通知 MySQL 的存储引擎: 应用 HASH !. 我一段时间也是这样胸有成竹的依照这个实践抉择索引类型的: 如果是准确的 equals 比拟查问, 那么就应用 HASH, 如果应用范畴查问和大小比拟查问那么最好应用 BTREE.
因为以前的开发经验就是性能开发为主, 对具体的细节不是很在意, 个别 MySQL 也能满足需要, 所以我天真的认为既然建表语句能够指定 HASH 而且没有报正告和谬误, 那么这个索引的底层数据结构必定是 HASH, 而后我就释怀的应用 equals 准确查问数据了. 直到有一天我看到 MySQL 的官网文档, 才对这个产生粗浅的反思.
原文如下:
Most MySQL indexes (PRIMARY KEY, UNIQUE, INDEX, and FULLTEXT) are stored in B-trees. Exceptions: Indexes on spatial data types use R-trees; MEMORY tables also support hash indexes; InnoDB uses inverted lists for FULLTEXT indexes.
什么? 绝大多少 MySQL index 是 BTREE? 除了空间地位数据应用了 RTREE 以及 MEMORY TABLE 以及应用倒排列表的 FULLTEXT indexes?
InnoDB 官网解读
而后我马上查看了 InnoDB 的文档:
发现 InnoDB 其实是不反对 HASH 索引的, 然而它能够应用称为Adaptive Hash
的技术来在表象上反对 HASH. 这也就是我为什么以前应用 InnoDB 引擎并指定 index 类型为 HASH 的来建表并执行 SQL 的时候, 性能仍然看起来失常的实质起因.
MyISAM 官网解读
我持续查看了 MyISAM 的文档:
那么很遗憾,MyISAM 也是不反对 Hash 的. 而且 MyISAM 也不反对相似 InnoDB 的 Adaptive Hash
的技术来在表象上反对 HASH.
所以咱们得出结论:
- MyISAM 和 InnoDB 不反对 HASH
- InnoDB 能够应用
Adaptive Hash
来间接反对 HASH - MEMOEY 能力同时反对 HASH 和 BTREE
咱们在建表时给某些字段增加 hash 索引, 或者前期为某表增加 hash 索引时, 如果他们的存储引擎为 InnoDB 或 MyISAM, 则 sql 脚本自身是不会报错的, 然而咱们会发现, 该 hash 索引字段的 index_type 依然为 BTREE. 这其实是 MySQL 为了关照应用习惯而做到一些非凡解决, 其实底层会疏忽你指定索引为 HASH 的逻辑, 仍然应用 BTREE
理论验证
本次我应用 MySQL8 作为测试环境, 通过理论的代码操作做理论的论证.
InnDB 验证
CREATE TABLE index_type_test (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(32) NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `name_UNIQUE` using hash(name)
) ENGINE = InnoDB;
而后咱们查问这个表的索引类型:
mysql> show index from index_type_test;
所以理论测试表明 InnoDB 会疏忽你指定的 HASH 类型, 仍然应用 BTREE
MyISAM 验证
CREATE TABLE index_type_test (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(32) NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `name_UNIQUE` using hash(name)
) ENGINE = MyISAM;
而后咱们查问这个表的索引类型:
所以理论测试表明 MyISAM 会疏忽你指定的 HASH 类型, 仍然应用 BTREE.
本文原创链接:
- MySQL InnoDB&MyISAM 反对 Hash 么
参考链接:
- InnoDB 和 MyISAM 是否反对 hash 索引