0

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

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

只是,我不知道如何使用它。方向令人困惑。似乎这是为 PostgreSQL 创建的。我正在使用的服务器上使用 MySQL 和 Python。我还能用它来索引我的数据库吗?

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

4

2 回答 2

1

在处理大量数据时,例如在这种情况下,您需要了解并利用结构来有效地处理它。您不能在数据库中有 blob 并期望神奇地索引它并进行快速搜索。

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

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

您可以使用如下表在 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 索引使用一种非常紧凑的格式,可以在内存中容纳尽可能多的数据,它只索引指纹的某些部分,甚至不存储整个哈希值,它会截断一些位。所有这些都是为了使搜索快速。在通常用于托管网站的普通服务器上,它仍然不够快。

于 2016-03-19T11:46:24.953 回答
0

在 MySQL 中,您可以通过定义要应用它的长度来在 BLOB/TEXT 上使用索引:

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

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

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

于 2016-03-15T23:06:47.487 回答