• 欢迎访问IT乐园(o゚▽゚)o
  • 推荐使用最新版火狐浏览器和Chrome浏览器访问本网站。

mysql 优化之伪哈希索引

database fhy 7年前 (2018-02-04) 4780次浏览 0个评论
文章目录[隐藏]

想法非常简单,在标准的 B-Tree 索引上创建一个伪哈希索引。它和真正的哈希索引不是一回事,因为它还是使用 B-Tree 索引进行查找。然而,它将会使用键的哈希值进行查找,而不是键自身。你所要做的事情就是在 where 子句中手动地定义哈希函数。

例子:URL 查找。

URL 通常会导致 B-Tree 索引变大,因为它们非常长。通常会按照下面的方式来查找 URL 表。

s... id from url where url='http://www.mysql.com';

但是,如果移除掉 url 列上的索引并且给表添加一个被索引的 url_src 列,就可以按照下面的方式进行查询:

s... id from url where url='http://www.mysql.com' and url_src=CRC32('http://www.mysql.com');

mysql 查询优化器注意到 url_src 列上有很小的,选择性很高的索引,并且它会使用里面的值进行索引查找。即使有几列相同的 url_src 值,也很容易进行精确的对比来确定需要的行。替代方案是把完整的 URL 索引为字符串,它要慢很多。

这个办法的一个缺点就是要维护哈希值。你可以手工进行维护,在 mysql5.0 以上版本中,可以使用触发器来进行维护。

1.创建一个表:

c... table pseudohash(
    id int unsigned NOT NULL auto_increment,
    url varchar(255) NOT NULL,
    url_src int unsigned NOIT NULL DEFAULT 0,
    PRIMARY KEY(id)
);  

接下来创建触发器。我们先暂时更新一下命令分隔符,这样就可以在触发器中使用分号:

DELIMITER
|
CREATE TRIGGER pseudohash_src_ins BEFORE INSERT ON pseudohash FOR EACH ROW BEGIN SET NEW.url_src = crc32(NEW.url);
END;
|
CREATE TRIGGER pseudohash_src_upd BEFORE UPDATE ON pseudohash FOR EACH ROW BEGIN SET NEW.url_src = crc32(NEW.url);
END;
|
DELIMITER;

剩下的工作就是验证触发器自动维护了哈希值。

如果使用这种方式,就不应该使用 SHA1()和 MD5()这此哈希函数。它们返回很长的字符串,会浪费大量的存储空间并且减慢比较速度。它们是强加密函数,被设计为不产生任务冲突。这并不是我们的目标。简单的哈希函数能在有较好性能的同时保证可接受的冲突率。当然,如果表有很多行并且 CRC32()产生了很多冲突,就要实现自己的 64 位哈希函数,要确保自己的函数返回整数,而不是字符串。

select conv(right(md5('http://www.mysql.com/'),16),16,10) as hash64;

IT 乐园 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:mysql 优化之伪哈希索引
喜欢 (0)
关于作者:
九零后挨踢男
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址