MySQL优化四-MySQL Innodb 自定义Hash索引

目录

哈希索引

InnoDB创建自定义哈希索引

维护哈希值


哈希索引

mysql 只有Memory引擎显示支持非唯一的哈希索引,如果多个列的哈希值相同,索引以链表的方式,存放多个记录指针,指到同一个哈希条目中。哈希索引的数据结构:槽 Slot、值 Value

每个槽的编号是顺序的,但是值不是。值存储的是指向 行 的指针

优点:
因为索引自身只需存储对应的哈希值,所以索引的结构十分紧凑,这也让哈希索引查找的速度非常快。

缺点:

1 哈希值是无序的,无法用于排序
2 哈希索引只支持等值比较如=、in()、<=>,,不支持任何范围查询,如where price > 100。
3 哈希冲突,索引维护操作代价很高
4 不支持部分列匹配查找。例如:对数据列(A,B)建立哈希索引,此时查询A列,无法使用该索引

因为这些限制,哈希索引只适用于某些特定的场合。而一旦适合哈希索引 ,则它带来性能提升将非常显著,比如数据仓库应用中的一种经典的星型schema,需要关联很多查找表,哈希表就适合查找表的需求。

InnoDB创建自定义哈希索引

当存储引擎不支持哈希索引时,可以自定义哈希索引,例如只需要很小的索引,可为超长的列值创建索引。

思路:在B-Tree创建一个伪哈希索引,它使用哈希值,而不是键本身进行索引比较,在where子句中,手动指定使用的哈希函数。

比如:

mysql> SELECT id FROM url WHERE url="http://www.mysql.com";

直接在url列值做索引,索引值会很大,若删除url列的索引,新增一个被索引的url_crc列,使用crc32做哈希,就可以用以下的查询,注意先查找索引列,再查找url列值:

mysql> SELECT id FROM url WHERE url_crc=CRC32("http://www.mysql.com") and url="http://www.mysql.com"

这样做的性能会非常高,使用了选择性高且体积小的基于url_crc的索引来完成查找。即使有多个记录有相同的索引值(哈希冲突),查找仍然很快,只需将查找到的多个记录,一一比较返回对应的行。

维护哈希值

这样实现的缺陷是需要维护哈希值,可以手动维护,也可以使用触发器实现。

DELIMITER // 
CREATE TRIGGER pseudohash_crc_in s BEFORE INSERT ON pseudohash FOR EACH ROW BEGIN 
SET NEW.url_crc=crc32(NEW.url); 
END; 
// 
CREATE TRIGGER pseudohash_crc_upd BEFORE UPDATE ON pseudohash FOR EACH ROW BEGIN 
SET NEW.url_crc=crc32(NEW.url); 
END; 
//

 剩下的工作就是验证触发器如何维护哈希索引:

mysql> INSERT INTO pseudohash_crc_in (url) VALUE("http://mysql.com");
mysql> select * from pseudohash_crc_in 

mysql> update pseudohash_crc_in set url = "http://mysql.com" where id = 1;
mysql> select * from pseudohash_crc_in 

查看下url_crc列值是否修改了。

你可能感兴趣的:(mariadb,哈希算法,数据库,算法)