0

現在、acoustid というオープン ソースの音楽認識プロジェクトをいじっています。3,000 万行 (300 GB のデータ) を超えるテーブルをインポートしましたが、これらの行を単純に選択するのに非常に時間がかかります。現在、200,000 行の選択には 30 秒かかる場合があります。

このプロジェクトは、フィンガープリントの最初の 15 秒間だけを検索し、これを hdd に保存することで、行にインデックスを付ける acoustid-index を提供しています。これは、RAM にロードされます。https://bitbucket.org/acoustid/acoustid-index/overview

ただ、これの使い方がわかりません。説明がわかりにくいです。これはPostgreSQL用に作成されたようです。作業中のサーバーで MySQL と Python を使用しています。これを使用してデータベースのインデックスを作成できますか?

これを使用してデータベース内の行にインデックスを付ける方法について何か提案はありますか? このデータベースでの検索をより効率的にする他の方法はありますか?

4

2 に答える 2

1

この場合のように、大量のデータを扱う場合は、構造を理解して活用し、効果的に処理する必要があります。データベースにブロブを作成して魔法のようにインデックスを作成し、検索を高速化することを期待することはできません。

テキスト ドキュメントがある場合、通常のアプローチは、テキストを解析し、そこから単語を抽出し、場合によっては後処理を行ってから、それらの単語のインデックスを作成する検索エンジンを使用することです。これは一般的な使用例であり、たとえば、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 インデックスは、できるだけ多くのデータをメモリに収める非常にコンパクトな形式を使用します。フィンガープリントの特定の部分のみにインデックスを付け、ハッシュ全体を保存することさえせず、一部のビットを切り捨てます。検索を高速化するために行われるすべてのこと。それでも、Web サイトのホスティングに通常使用される平均的なサーバーでは十分な速度ではありません。

于 2016-03-19T11:46:24.953 に答える