如何更高效地搜索超过 3000 万行的 acoustid 数据库?

How to more efficiently search through an acoustid database with over 30 million rows?

我目前正在研究一个名为 acoustid 的开源音乐识别项目。我已经导入了一个包含超过 3000 万行(300gb 数据)的 table,但是简单地 SELECT 这些行需要花费大量时间。目前,选择 200,000 行可能需要 30 秒。

该项目提供 acoustid-index 来索引行,方法是仅查找指纹的前 15 秒并将其存储在硬盘上...然后加载到内存中。 https://bitbucket.org/acoustid/acoustid-index/overview

只是不知道怎么用this.The 方向很乱。这似乎是为 PostgreSQL 创建的。我正在使用的服务器上使用 MySQL 和 Python。我还能用它来索引我的数据库吗?

关于我如何使用它来索引数据库中的行有什么建议吗?有没有其他方法可以使通过该数据库的搜索更有效?

在 MySQL 中,您可以在 BLOB/TEXT 上使用索引,方法是定义要应用此索引的长度:

CREATE INDEX idx_nn_1 ON sometable(accoustic(500));

这会将前 500 个字节编入索引作为您的指纹(即:不是 15 秒)。

要达到 15 秒,您可以使用 MD5SUM,将其添加为额外的列,然后查询那 15 秒的 MD5SUM。或者,您可以对整首歌曲使用 MD5SUM。

在处理大量数据时(如本例),您需要了解并利用结构才能有效地使用它。你不能在你的数据库中有一个 blob 并期望神奇地索引它并进行快速搜索。

如果您有文本文档,通常的方法是使用搜索引擎来解析文本,从中提取单词,可能会对它们进行一些 post 处理,然后在这些上创建索引字。这是一个常见的用例,例如 MySQL 全文索引就是这样做的。

在你的例子中,你有 Chromaprint 产生的声学指纹,这是不太常见的用例。没有可以加快搜索速度的内置解决方案。如何索引数据以及如何搜索数据取决于您。您需要了解指纹由 32 位哈希(相当于文本文档中的单词)组成,并且您需要了解倒排索引的工作原理。如果你通过哈希索引指纹,你就不需要扫描整个数据库,你只会在你的倒排索引中寻找特定的哈希。

您可以使用 table 在 MySQL 中构建一个非常粗糙的倒排索引,如下所示:

CREATE TABLE fingerprint_hash (
  hash INT NOT NULL,
  fingerprint_id INT NOT NULL,
);

然后加载数据并创建物理索引:

CREATE INDEX fingerprint_hash_idx_hash ON fingerprint_hash(hash);

有了这个之后,您可以像这样查询索引:

SELECT fingerprint_id, COUNT(*) AS num_matching_hashes
FROM fingerprint_hash
WHERE hash IN (627833118,627767582,627697982,627624254,627956095,...)
GROUP BY fingerprint_id

这将为您提供具有一些通用哈希值的指纹 ID。

请注意,上述操作很可能仍然很慢。自定义 AcoustID 索引使用一种非常紧凑的格式,可以在内存中容纳尽可能多的数据,它只索引指纹的某些部分,甚至不存储整个哈希值,它会截断一些位。所做的一切都是为了加快搜索速度。在通常用于托管网站的普通服务器上,它仍然不够快。