2

私は3つのテーブルを含む大規模な(〜10GB)SQLiteデータベースを扱っています:IDと「タイトル」TEXT列を含むドキュメント、IDと「用語」TEXT列を含む用語、そして最後にid、 "documentId" INT、および "termId"INTで、Terms テーブルの行を Document テーブルの行にマッピングします。ドキュメントに同じ用語が複数回含まれている場合、DocumentTerms テーブルには複数のエントリがあります。

とにかく、私の問題は、次の手順を含む各用語で tfidf 用語の重みを実行する必要があることです (各ステップを取得する必要があると思われるクエリを含めました)。

  1. すべての文書で用語が何回出現するかを調べる -SELECT COUNT(*) FROM DocumentTerms WHERE termId=id
  2. 文書の総数を調べる -SELECT COUNT(*) FROM Documents
  3. 用語が出現する文書の数を調べる --SELECT COUNT(*) FROM DocumentTerms WHERE termId=id GROUP BY documentId

明らかに、#2 を実行する必要があるのは 1 回だけです。

このような大規模なデータベースでは、各クエリに非常に長い時間がかかります。ドキュメントの数 ( ) を調べるだけで、SELECT COUNT(*) FROM Documents約 45 秒かかります。

速度を上げるために、いくつかのプラグマを試しました。これを実行する必要があるのは 1 回だけなので、操作中に電源が切れたり何かが失われた場合に DB が破損するかどうかはあまり気にしません。

PRAGMA synchronous = OFF
PRAGMA page_size = 4096
PRAGMA cache_size = 16384
PRAGMA temp_store = MEMORY
PRAGMA journal_mode = OFF
PRAGMA locking_mode = EXCLUSIVE

これらのアクセス時間を短縮するにはどうすればよいですか??

4

1 に答える 1

1

読み取り専用アクセスの場合、これらPRAGMAのほとんどは効果がありません。だけcache_sizeが重要です。page_size少し役立つかもしれませんが、DB を作成する前に設定する必要があります。

シンプルSELECT COUNT(*)にそれほど時間がかかる場合、有用なインデックスがないことは明らかです。データベース構造がないとわかりにくいですが、次のインデックスが役立つ可能性があります。

CREATE INDEX Documents_Id ON Documents(Id)

( の代わりに、テーブルの任意の小さなフィールドをId使用できますが、通常は主キーにインデックスを付けることをお勧めします。)Documents

CREATE INDEX DocumentTerms_termId_documentId ON DocumentTerms(termId, documentId)

EXPLAIN QUERY PLANでクエリがどのように実行されるかを確認できます。

于 2013-07-28T08:31:46.953 に答える