任意の部分文字列の一致を最適化する場合、1つのオプションは、<コードを使用することです。> pg_tgrm モジュール 。インデックスを追加する:
CREATE INDEX table_location_name_trigrams_key ON table
USING gin (location_name gin_trgm_ops);
これにより、「Simple Cafe」が「sim」、「imp」、「mpl」などに分割され、各行の各trigamのインデックスにエントリが追加されます。クエリプランナーは、次のような部分文字列パターンの一致にこのインデックスを自動的に使用できます。
SELECT * FROM table WHERE location_name ILIKE '%cafe%';
このクエリは、インデックスで「caf」と「afe」を検索し、共通部分を見つけ、それらの行をフェッチしてから、各行をパターンと照合します。 (「caf」と「afe」の共通部分は「simplecafe」と「unsafescaffolding」の両方に一致するのに対し、「%cafe%」は1つにのみ一致するため、最後のチェックが必要です)。より多くの行を除外できるため、入力パターンが長くなるにつれてインデックスはより効果的になりますが、それでも単語全体のインデックスを作成するほど効率的ではないため、 to_tsvector
よりもパフォーマンスが向上することは期待できません。 。
キャッチは、トリグラムは3文字未満のパターンではまったく機能しません。これは、アプリケーションにとって大きな問題になる場合とそうでない場合があります。
編集: 最初にこれをコメントとして追加しました。
昨夜、ほとんど眠っていたとき、私は別の考えを持っていました。 cjk_chars
を作成します 入力文字列を受け取る関数、 regexp_matches
CJK Unicodeの範囲全体であり、そのような文字の配列または NULL
を返します。 ない場合。 cjk_chars(location_name)
にGINインデックスを追加します 。次に、次のクエリを実行します:
WHERE CASE
WHEN cjk_chars('query') IS NOT NULL THEN
cjk_chars(location_name) @> cjk_chars('query')
AND location_name LIKE '%query%'
ELSE
<tsvector/trigrams>
END
タダ、ユニグラム!