6

オートコンプリート機能を実行する必要があり、次のようなことをする必要があります:

select field from huge_table where field like '%some string%';

テーブルは 200 万行あり、迅速かついくつかの応答が必要です。Postgres を使用しています。そして、その種のクエリには永遠に時間がかかります。

postgresでこれを行う効率的な方法はありますか? それとも、postgres 以外のものを使用する必要がありますか?

ありがとう!

4

4 に答える 4

3

オートコンプリートを行っている場合は、プレフィックスに基づいて一致を探していると思います。接頭辞ベースのルックアップの標準データ構造はtrieです。

インデックスとプレフィックス ベースのルックアップ ( some string%) を使用して postgres から適切なパフォーマンスを得ることができない場合は、定期的に 200 万行すべての完全なクエリを実行し、トライを構築するか、データベースと並行してトライを維持することができます。

Trie の最悪の場合のパフォーマンスは ですO(m)。ここで、mはプレフィックスの長さです。したがって、構築されると、非常に高速なオートコンプリートが提供されます。

于 2013-03-28T21:06:35.450 に答える
1

ユースケースの詳細によっては、tsquery単語の接頭辞を照会するための構文があることを知っておく価値があるかもしれません。これをインデックス付きフィールドと組み合わせると、tsvector単語のプレフィックスを非常に高速に検索できます。

「巨大な」テーブルを作成します。

CREATE TABLE huge_table (
    field       text,
    field_tsv   tsvector
);

インデックスを追加します。

CREATE INDEX field_tsv_idx ON huge_table USING gin(field_tsv);

インデックス付き列を更新するトリガーを追加します。

CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE
ON huge_table FOR EACH ROW EXECUTE PROCEDURE
tsvector_update_trigger(field_tsv, 'pg_catalog.english', field);

モックデータを追加する

INSERT INTO huge_table (field) VALUES ('something nice');
INSERT INTO huge_table (field) VALUES ('another thing');

次に、何らかの制限のあるプレフィックスをクエリします。

SELECT field FROM huge_table WHERE field_tsv @@ to_tsquery('anot:*') LIMIT 20;
     field     
---------------
 another thing
(1 row)

インデックスがかなり大きくなる可能性があるため、特にインデックスの種類についてドキュメントを読んでください。

于 2013-03-28T23:01:56.970 に答える
1

検索対象にインデックスを追加できますfield

また、回避可能な場合は、パフォーマンスを大幅%some string%に低下させるため、無制限のワイルドカードを使用しないでください。可能であれば、実行してください。some string%

于 2013-03-28T20:59:44.360 に答える
1

追加の挿入/更新時間に余裕がある場合は、おそらく pg_trgm 拡張機能を使用できます

最良のシナリオでの改善を確認するために、200 万レコード テーブルとのリンクにいくつかのテストがあります。

于 2013-03-28T21:13:56.470 に答える