0

ソースから sqlite3 をビルドして FTS3 サポートを組み込み、150 万行のデータを含む既存の sqlite データベースに新しいテーブルを作成しました。

CREATE VIRTUAL TABLE data USING FTS3(codes text);

その後、使用

INSERT INTO data(codes) SELECT originalcodes FROM original_data;

次に、各テーブルをクエリしました

SELECT * FROM original_data WHERE originalcodes='RH12';

その列にインデックスがあるので、これはすぐに戻ってきます

FTS3 テーブルに対するクエリ

SELECT * FROM data WHERE codes='RH12';

約28秒かかります

これがかなり速いと思っていたので、誰かが私が間違ったことを説明するのを手伝ってくれますか

4

3 に答える 3

3

ドキュメントでは次のように説明されています。

FTS テーブルは、次の 2 つの異なる形式の SELECT ステートメントを使用して効率的にクエリできます。

  • ROWID によるクエリ。SELECT ステートメントの WHERE 句に「rowid = ?」という形式のサブ句が含まれている場合、? は SQL 式です。FTS は、SQLite の INTEGER PRIMARY KEY インデックスに相当するものを使用して、要求された行を直接取得できます。
  • 全文クエリ。SELECT ステートメントの WHERE 句に「 MATCH ?」という形式のサブ句が含まれている場合、FTS は組み込みのフルテキスト インデックスを使用して、指定されたフルテキスト クエリ文字列に一致するドキュメントに検索を制限できます。 MATCH 句の右側のオペランドとして。

これら 2 つのクエリ戦略のいずれも使用できない場合、FTS テーブルに対するすべてのクエリは、テーブル全体の線形スキャンを使用して実装されます。

効率的なクエリのために、使用する必要があります

SELECT * FROM data WHERE codes MATCH 'RH12'

ただし、これにより、検索文字列を含むすべてのレコードが検索されます。

「通常の」クエリを効率的に実行するには、通常のテーブルにデータのコピーを保持する必要があります。(スペースを節約したい場合は、コンテンツのないテーブルまたは外部コンテンツテーブルを使用できます。)

于 2013-02-03T20:44:59.687 に答える
0

ドキュメントをもっと注意深く読む必要があります。

を使用した仮想FTSテーブルに対するWHERE col = 'value'クエリは遅くなりますが(に対するクエリを除くROWID)、を使用したクエリWHERE col MATCH 'value'はFTSを使用して高速になります。

于 2013-02-03T20:29:01.827 に答える
0

私はこれについての専門家ではありませんが、ここで考えるべきことがいくつかあります。あなたのテストには欠陥があります(私は思います)。テキストが完全に一致するシナリオ(元のデータでインデックスを使用できます-このシナリオよりも優れたものはありません)と、fts3テーブルの同等性(FTS3が機能するかどうかはわかりません)と対比していますこのタイプのクエリ)。リンゴとリンゴを比較したい場合 (FTS3 の利点を確認するため)、original_data に対する "like" 操作とデータに対する FTS3 "match" 操作を比較する必要があります。

于 2013-02-03T20:32:17.590 に答える