如何解决我应该使用MD5 32个字符的MySQL索引还是包含特殊字符的〜8字符索引?
我有一个大约1亿个url的数据库,出于分片目的(并标识唯一的url),我将每个条目索引设为完整url的md5哈希。
MD5仅由16个可能的字符组成:0123456789abcdef
,总长度为32个字符。
如果我使用较短的索引(例如8个字符),我应该期待哪些性能优势(如果有的话)?例如,使用包含大写,小写和特殊字符的哈希函数(可能是自定义的)。
还是因为索引使用更多可能的字符而导致性能下降? (即使索引长度较短〜8)。
解决方法
简短的回答::我建议使用INDEX(hash,id)
的计划C,确保它是次要索引。
好答案和一些讨论:
计划A:只需使用网址即可。效率最低。
方案B:将32字节的CHAR(32) CHARSET ascii
用于十六进制MD5。更好但不是最好。
计划C:UNHEX(..)
,然后放入BINARY(16)
(16字节)。更好。
计划D(根据您的建议):仅使用这16个字节中的一些。 将重复一些。这可能会削弱使用较短摘要的速度优势。
计划E:位模式加查找。可能甚至更快。 (但是首先,让我解释一些问题。)
您有多少RAM?你有多少磁盘?
大概磁盘上有10-20GB的空间。但是,您还有更多的RAM吗?如果您不这样做,那么我们需要讨论缩小查找范围,否则 all 计划将退化为必须以一定的频率命中磁盘。
桌子是什么样的?
- 哈希+完整URL +杂项;
id
或hash
为PRIMARY KEY
- INDEX(hash,id)-您将在这里花费大部分精力,这比整个表小得多。对于Plan C,此二级索引对于1亿行大约需要5GB。您会四处走动,因此除非所有5GB内存都可以在RAM中生存,否则缓存不是很好。
- 计划E尝试通过首先查看可以将查找压缩为0.2GB的位字符串来缩小索引。将有 重复项,需要重复检查(例如计划C),但可能只有5-10%的时间。如果您愿意,我们可以进一步讨论。
为进一步讨论,请提供RAM大小,完整的CREATE TABLE
和建议的“检查重复项” SELECT
。
尺寸
- 1位只能代表2个不同的值
- 1个十六进制数字只能代表4个不同的值
- 1个字节(8位)可以表示256(2 ^ 8)个不同的值
- 100M〜= 2 ^ 23(用于比较)
- INT是4个字节:2 ^ 32,足够容纳1..100M
- BIGINT为8个字节:2 ^ 64,大于几乎所有
id
用法所需的大小 - 8个字节,假设您使用所有可能的组合:256 ^ 8 = 2 ^ 64 =一个非常大的数字
- MD5具有128位(表示为32个十六进制数字或16个二进制字节):2 ^ 128-更大的数字
判断重复的可能性:
- 给出2 ^ M-例如,对于MD5,M = 128; BIGINT为64
- 计算N =(M + 1)/ 3-MD5:43; BIGINT:〜22
- 说:在2 ^ N行中找到dup的几率是1/2 ^ N。
也就是说,
- 与md5进行重复运算的几率:如果您具有2 ^ 43(9万亿)的值,则只有9万亿分之一。
- 具有8字节哈希的重复数据的几率:如果有600万行,则重复数据的机会约为600万分之一。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。