WEB开发网
开发学院数据库MySQL Schema的优化和索引 - 索引的基础 - 索引的类型 -... 阅读

Schema的优化和索引 - 索引的基础 - 索引的类型 - Hash索引

 2009-09-02 00:00:00 来源:WEB开发网   
核心提示: 如果你使用这种方法,不要使用SHA1()和MD5这些hash函数,Schema的优化和索引 - 索引的基础 - 索引的类型 - Hash索引(5),这些返回了非常长的字符串,这会浪费空间和降低比较的速度,这个情况下,你可能执行的是关于统计的语句而不需要准确的结果,这两个函数密码性很强,也会消除冲

如果你使用这种方法,不要使用SHA1()和MD5这些hash函数。这些返回了非常长的字符串。这会浪费空间和降低比较的速度。这两个函数密码性很强,也会消除冲突,但在这里这并不是我们的目标。简单的hash函数所造成的冲突是可容忍的并且还有良好的性能。

如果你的表中有很多行,CRC32函数可以造成太多的冲突。你可以自己实现64bit的hash函数。要确定的是,你使用的函数必须返回的是整型,并不是个字符串。实现64bit hash函数的方法是使用MD5所返回的一部分。这可能会比自定义函数的性能要差一些,但是必要时可以这么做。

mysql> SELECT CONV(RIGHT(MD5('http://www.mysql.com/'), 16), 16, 10) AS HASH64;
+---------------------+
| HASH64 |
+---------------------+
| 9761173720318281581 |
+---------------------+

Maatkit(http://maatkit.sourceforge.net)包含了一个自定义函数,实现了一个Fowler/Noll/Vo 64bit hash函数。它的速度也非常快。

处理hash冲突

如果你要使用hash来搜索的话,你必须要在WHERE条件中包含它hash之前的值。比如

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

下面的语句就不是正确的。因为另一个URL的Hash值也是1560514994,这个语句会把它们都查找出来。

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

Hash的冲突情况增长的速度可能超出你的想象。这是由于所谓的Birthday Paradox所引起的。CRC32()返回的一个32bit整型值。因此可能93000值就会有1%的冲突。为了证明这点,我们把/usr/share/dict/words所有word写入到表中。结果写入了98,569行。已经有了一个冲突了。冲突会使以下的查询返回很多行

mysql> SELECT word, crc FROM words WHERE crc = CRC32('gnu');
+---------+------------+
| word | crc |
+---------+------------+
| codding | 1774765869 |
| gnu | 1774765869 |
+---------+------------+

正确的查询语句

mysql> SELECT word, crc FROM words WHERE crc = CRC32('gnu') AND word = 'gnu';
+------+------------+
| word | crc |
+------+------------+
| gnu | 1774765869 |
+------+------------+

为了避免冲突,你必须在where条件中同时指定这两个条件。如果冲突不是一个问题,就在WHERE条件后仅仅指定CRC32,这个情况下,你可能执行的是关于统计的语句而不需要准确的结果。这样还能获得更高的效率。

上一页  1 2 3 4 5 

Tags:Schema 优化 索引

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接