我有一个表,其中一列存储哈希值中的图像src,并且该哈希值是从microtime()生成的,现在我有两种选择将哈希值直接存储在数据库中或存储从中派生图像名称的bigint微时间。这将使我的数据库更快。
我们必须从各个方面分析这一点,以评估会产生哪些速度故障。
我将做出一些假设:
- 此数据将用作标识符(主键、唯一键、复合键);
- 此数据用于搜索和联接; 您正在使用哈希算法,例如 SHA1,它生成一个 40 个字符的十六进制编码数据字符串(MD5
- 产生一个 32 个字符的十六进制编码数据字符串,如果您正在使用的话,所有上述波纹管都可以适应 MD5);
- 您可能有兴趣将哈希的十六进制值转换为二进制,以将所需的存储减少一半并提高比较速度;
在应用程序端插入和更新:
如@Namphibian所述,BIGINT 由 2 个操作组成,而 CHAR 由 3 个操作组成。
但在我看来,速度差异真的没有那么大。您可以运行 10.000.000 次连续计算(在while
循环中)并对它们进行基准测试以找出它们之间的实际差异。
当流量增加时,数据库的速度差异会非线性地影响用户,因为重叠的写入必须相互等待,而某些读取必须等待写入完成。
在数据库端插入和更新:
对于 BIGINT 与 CHAR(40) 或 BINARY(20) 几乎相同,因为更严重的时间消耗是在等待访问磁盘而不是实际写入磁盘时完成的。
在数据库端选择和加入:
与 CHAR(40) 或 BINARY(20) 相比,BIGINT 总是更快,原因有两个:
- BIGINT 以 8 字节存储,而 CHAR(40)
- 以 40 字节存储,BINARY(20) 以 20 字节存储;
- BIGINT 的连续递增特性使其具有可预测性且易于比较和排序。
第二个最佳选择是 BINARY(20),因为它节省了一些空间,并且由于长度减小而更容易比较。
BINARY(20) 和 CHAR(40) 都是散列机制的结果,并且是随机的,因此比较和排序平均需要更长的时间,因为索引中的随机数据(对于 btree 索引)需要更多的树遍历来获取(我的意思是在多个值的上下文中,而不是对于单个值)。
一个重要的科学原则可能适用于这里:不要丢失原始数据。你永远不知道你可能需要它做什么。