加快我在 MySQL 中的索引 - CRC 还是 MD5?

Posted

技术标签:

【中文标题】加快我在 MySQL 中的索引 - CRC 还是 MD5?【英文标题】:Speed up my indexes in MySQL - CRC or MD5? 【发布时间】:2012-09-22 14:46:52 【问题描述】:

我有一个包含 8 300 000 行的大表(永远不会被编辑或删除)。

我的第一列与P300-4312B_X16_S 类似,并且该条目不是唯一的,因此我在此字段上使用常规索引。

但是,mysql 使用二进制字段而不是 varchar 更快,因此我使用 BINARY(16) 将我的 INDEX 编码为 MD5 来存储数据。

今天早上第一次开始使用CRC32,看到CRC32可以输出为8个字符的十六进制字符串。

我的问题:如果我使用 CRC32 而不是 MD5,它会更快。但是,当 CRC32 运行时,假设 2 000 000 个唯一值,结果将是唯一的,或者有时我会为两个不同的字符串提供两次相同的字符串?我这样问是因为结果只有 8 个字符 (32b) 长,而不是像 MD5 那样的 32(128b)。

谢谢。

【问题讨论】:

请看这个页面:dslreports.com/forum/remark,13525942 当然你会遇到更多的 CRC32 冲突。它是用于数据完整性检查的工具,而不是像 md5 这样的哈希函数。哈希函数旨在产生尽可能少的冲突(不同输入的相同结果)。 CRC 不是。 However, MySQL is WAY faster using a binary field instead of a varchar so I encode my INDEX in MD5 using BINARY(16) to store the data. 听起来您的索引已损坏。在VARCHAR 上建立索引应该可以正常工作.. 对于 dmitry,与 md5 相比,使用 crc32 获得更多的冲突与设计几乎无关,而与位数有关。 crc32 将导致与任何其他良好的 32 位散列函数相同数量的冲突。同样,一个 128 位的 crc 将导致与 md5 相同的冲突概率。 md5 除了 crc 之外还有另一个设计要求,即它不能可逆地用于加密应用程序。该属性对意外碰撞没有影响。它所做的只是防止,或者更确切地说是制造非常困难的人为碰撞。 @Mark Adler 不能同意“与设计无关”。 Md5 是设计的哈希算法。 Crc 是校验和,旨在检测该上下文中的位错误和冲突,就在域外。 【参考方案1】:

预期的冲突数是对数超过可能的检查值数。因此,对于 2,000,000 个值,有 (2000000 * 1999999) / 2 对,大约为 2x1012。对于 32 位 CRC,预期的冲突次数超过 232,即 466。因此,在这种情况下,您基本上肯定会发生冲突。

对于 128 位 MD5 校验值,预期的冲突次数约为 6x10-27。对于期望数的小值,这也是一次碰撞的概率。

如果碰撞概率非常低对您很重要,那么您需要选择除 CRC-32 之外的其他内容。

不过,您不需要 MD5 的开销,因为它的加密强度对您的应用程序并不重要。您并不真正关心是否有人恶意可以找到一种方法来伪造与另一个条目具有相同检查值的条目。因此,您可以使用为此目的而设计的 64 位非加密哈希,它会运行得更快,并且在您的 2,000,000 个值的情况下会产生 10-7 的冲突概率。或者您可以使用 128 位非加密散列并获得与 MD5 相同的概率,但要快得多。看看哈希算法的CityHash family。

但是请注意,在所有情况下,发生碰撞的概率都不是零。您应该考虑代码冲突的后果。

【讨论】:

我喜欢您的回答,因为我现在了解“哈希”背后的逻辑。我不在乎访问者是否找到了编码的哈希,它只是为了定义一次公共汽车旅行。如果他找到了,那么他会找到一个随机的公共汽车旅行......没什么大不了的。我来看看 CityHash 家族。谢谢。

以上是关于加快我在 MySQL 中的索引 - CRC 还是 MD5?的主要内容,如果未能解决你的问题,请参考以下文章

Mysql 数据库表中有索引为什么还是查询慢?

带有索引的 MySQL 表:许多插入/更新会影响性能吗?如果是,如何再次加快速度?

Mysql索引学习笔记

MySQL的索引

oracle中加索引会不会加快更新的速度?有人说会减慢更新速度?谁知道为啥吗?

具有 10+ 百万行的 MySQL 表 - 如何使用索引加快搜索速度?