最大限度地提高数据库性能

时间:2017-08-01 17:29:32

标签: mysql performance indexing hash

我有数字化图像哈希,哈希就像2k整数长。 什么是将其存储在数据库和搜索中的最佳解决方案? 行数至少为300万。对性能的建议?  我正在考虑创建utf8_bin校对列并将所有数字转换为区分大小写的哈希并在列上添加索引,还是有其他更好的解决方案?

P.S。 hash可以修改,1k整数会不太准确,所以我更喜欢存储2k左右。

2 个答案:

答案 0 :(得分:2)

存储long的最紧凑方法是使用VARBINARY数据类型存储为二进制字节,而不是使用utf8_bin collat​​ion存储的字符串。计算图像的数字哈希值,转换为十六进制数字字符串,然后使用UNHEX()转换为二进制字节。二进制字节存储在等效的十六进制数字字符串的一半空间中。例如,像'FFFF'这样的字符串需要四个字符,但UNHEX('FFFF')存储在两个二进制字节中。

单独存储更紧凑只是对性能的适度改进 更好的性能优势是使用索引。但InnoDB对索引长度有限制。默认情况下,限制为767字节。

如果设置innodb_large_prefix=1,可以将InnoDB增加到3072字节(必须使用DYNAMIC或COMPRESSED行格式,这意味着必须使用每表文件)。这应该足以索引哈希的整个长度。

更新:我在MySQL 5.7.7和MariaDB 10.2中了解到innodb_large_prefixdeprecated,该选项将在以后的版本中删除。但不要担心,它已被弃用,因为大索引支持将成为默认行为。不再需要该选项,因为它实际上始终处于开启状态。

CREATE TABLE MyTable (
  dhash VARBINARY(3072) NOT NULL,
  UNIQUE KEY (dhash)
);

答案 1 :(得分:0)

  • MD5只有128位,只能存储在BINARY(16)中的16个字节中如果你有9个万亿图像,那么9万亿个图像中只有一个机会假的。仅仅3 百万行,赔率甚至更小。

  • 因此,我反对需要2K整数。 (或者您的意思是数字?)有一些库例程可以获取任意字符串或文件并快速消化为md5。 (或sha1或sha256等)不要编写自己的哈希码。

  • 不要将utf8用于任何只有数字的字符串;使用CHARACTER SET ascii COLLATE ascii_bin。 (但上面的BINARY甚至更好;只是如果你来自一串数字就不实用。)

  • 如果字符串或blob是固定长度,请不要使用VAR...

  • 如果您必须使用数字并使用767限制,那么实际的方法是使用2 * 767数字和UNHEX()并存储到BINARY(767)。 (如果变长,则为“VARBINARY(767)”。

  • 在5.7.7之前的版本中,有4个步骤可以达到3072:http://mysql.rjweb.org/doc.php/limits#767_limit_in_innodb_indexes