【问题标题】:Maximize database performance for very long digit最大化非常长数字的数据库性能
【发布时间】:2018-01-08 16:51:57
【问题描述】:

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

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

【问题讨论】:

  • 如果你需要性能,为什么是 MySQL 而不是其他的... MariaDB // Reddis // Percona...等。等
  • 其实我在用mariadb
  • 存储在数据库中搜索?你会做什么搜索?哈希是哈希,所以只有选项等于。如果是这样,为什么还要使用 2k 哈希,只需使用较小的 64 位哈希就可以了,然后在需要时进行重复数据删除。
  • 使用一些像mongodb这样的键值数据库
  • 最长哈希 - 准确的图像识别,我将存储超过 300 万张图像,因此准确性很重要,而且我不会存储重复项

标签: mysql performance indexing hash


【解决方案1】:

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

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

如果您设置innodb_large_prefix=1,您可以将 InnoDB 增加到 3072 字节(您必须使用 DYNAMIC 或 COMPRESSED 行格式,这意味着您必须使用 file-per-table)。这应该足以索引您的哈希的全长。


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

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

【讨论】:

  • 好主意,但是 innodb_large_prefix 在以后的 mariadb 版本中不会被弃用吗?
  • 我不知道。我不使用也不关注 MariaDB。
  • 你能推荐 mysql Ver 15.1 Distrib 10.1.24-MariaDB, for Linux (x86_64) using readline 5.1 的哈希表和索引表设置吗? id+hash 列,但其他参数?
【解决方案2】:
  • MD5 只有 128 位,在 BINARY(16) 中只能存储在 16 个字节中.对于仅仅 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 之前的版本中获取 3072 有 4 个步骤:http://mysql.rjweb.org/doc.php/limits#767_limit_in_innodb_indexes

【讨论】:

  • 问题是,例如 php imagemagick 或 gd 库在将图像调整为 32x32 大小时,有时会创建不同的图像,但所有像素中的 rgb 值都相同,因此收集起来非常昂贵例如,相同视觉图像的 2-200 md5 散列,但到处都有相同的像素。我决定用 32x32 的每个像素制作完整的字符串,然后从中进行 sha256 哈希,然后将此哈希存储到数据库中。
  • 我相信,消化完整图像比调整图像大小要快
  • 当然更快,但它并不准确,在我看来,最好存储 1 个哈希并使用更多 cpu 生成它,而不是在数据库中保留少数 2-200 个哈希作为“唯一”跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-18
相关资源
最近更新 更多