假设我想使用哈希作为ID而不是数字。将它们作为BINARY
存储在非二进制文件中是否具有性能优势?
CREATE TABLE `test`.`foobar` (
`id` CHAR(32) BINARY CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
PRIMARY KEY (`id`)
)
CHARACTER SET ascii;
答案 0 :(得分:29)
是。通常,哈希摘要存储为十六进制数字的ASCII表示,例如“哈希”一词的MD5为:
0800fc577294c34e0b28ad2839435945
这是一个32个字符的ASCII字符串。
但是MD5确实产生了128位的二进制哈希值。此应该只需要将16个字节存储为二进制值而不是十六进制数字。因此,您可以通过使用二进制字符串来获得一些空间效率。
CREATE TABLE test.foobar (
id BINARY(16) NOT NULL PRIMARY KEY
);
INSERT INTO test.foobar (id) VALUES (UNHEX(MD5('hash')));
重新。你的意见是你更关注绩效而不是空间效率:
我不知道BINARY数据类型比CHAR更快的原因。
如果您有效地使用缓存缓冲区,那么一半大可以提高性能。也就是说,如果字符串的大小是以十六进制存储相同值所需的CHAR的一半,则给定数量的高速缓冲存储器可以存储两倍于BINARY数据的行。同样,该列上索引的高速缓存也可以存储两倍。
结果是一个更有效的缓存,因为随机查询更有可能命中缓存的数据或索引,而不需要磁盘访问。缓存效率对于大多数数据库应用程序很重要,因为通常瓶颈是磁盘I / O.如果你可以使用高速缓冲存储器来降低磁盘I / O的频率,那么降压比一种数据类型或另一种数据类型之间的选择要大得多。
至于存储在BINARY中的哈希字符串与BIGINT之间的区别,我会选择BIGINT。缓存效率会更高,而且在64位处理器上整数运算和比较应该非常快。
我没有测量来支持上述声明。选择一种数据类型而不是另一种数据类型的净收益很大程度上取决于数据库和应用程序中的数据模式和查询类型。要获得最精确的答案,您必须尝试两种解决方案并衡量差异。
重新。假设二进制字符串比较比默认的不区分大小写的字符串比较更快,我尝试了以下测试:
mysql> SELECT BENCHMARK(100000000, 'foo' = 'FOO');
1 row in set (5.13 sec)
mysql> SELECT BENCHMARK(100000000, 'foo' = BINARY 'FOO');
1 row in set (4.23 sec)
因此二进制字符串比较比不区分大小写的字符串比较快17.5%。但请注意,在评估此表达式1亿次后,总差异仍然小于1秒。虽然我们可以测量速度的相对差异,但速度的绝对差异实际上是微不足道的。
所以我会重申:
答案 1 :(得分:6)
来自the manual:
The BINARY and VARBINARY types are similar to CHAR and VARCHAR, except
that they contain binary strings rather than non-binary strings. That is,
they contain byte strings rather than character strings. This means that
they have no character set, and sorting and comparison are based on the
numeric values of the bytes in the values.
因为CHAR(32)BINARY导致在引擎盖下创建BINARY(32)列,所以好处是它按照该列排序所需的时间更少,如果列是,则查找相应行的时间可能更短索引。