@willglynnがすでに投稿したものと同様に、pg_trgmモジュールを検討します。ただし、GiSTインデックスを使用することをお勧めします。
CREATE INDEX tbl_location_name_trgm_idx
USING gist(location_name gist_trgm_ops);
gist_trgm_ops
演算子クラスは一般的に大文字と小文字を区別せず、と同じILIKE
くらい高速LIKE
です。ソースコードの引用:
注意:IGNORECASEマクロは、トリグラムで大文字と小文字が区別されないことを意味します。
私はCOLLATE "C"
ここで使用します-これは事実上特別な照合ではありません(代わりにバイトオーダー)。これは明らかに、列にさまざまな照合が混在しているためです。照合は順序や範囲に関連しています。基本的な類似性検索では、照合なしで実行できます。COLLATE "C"
まず、コラムの設定を検討します。
このインデックスは、クエリの最初の単純な形式をサポートします。
SELECT * FROM tbl WHERE location_name ILIKE '%cafe%';
- とても早い。
- 部分一致を見つける機能を保持します。
- あいまい検索の機能を追加します。演算子とを
チェックしてください。%
set_limit()
- GiSTインデックスは、
LIMIT n
n個の「最適な」一致を選択するクエリに対しても非常に高速です。上記のクエリに追加できます。
ORDER BY location_name <-> 'cafe'
LIMIT 20
「距離」演算子の詳細については、<->
こちらのマニュアルをご覧ください。
あるいは:
SELECT *
FROM tbl
WHERE location_name ILIKE '%cafe%' -- exact partial match
OR location_name % 'cafe' -- fuzzy match
ORDER BY
(location_name ILIKE 'cafe%') DESC -- exact beginning first
,(location_name ILIKE '%cafe%') DESC -- exact partial match next
,(location_name <-> 'cafe') -- then "best" matches
,location_name -- break remaining ties (collation!)
LIMIT 20;
私は(私にとって)満足のいく結果を得るために、いくつかのアプリケーションでそのようなものを使用しています。もちろん、複数の機能を組み合わせて適用すると、少し遅くなります。あなたのスイートスポットを見つけてください...
さらに一歩進んで、言語ごとに個別の部分インデックスを作成し、それぞれに一致する照合を使用することができます。
CREATE INDEX location_name_trgm_idx
USING gist(location_name COLLATE "de_DE" gist_trgm_ops)
WHERE location_name_language = 'German';
-- repeat for each language
これは、クエリごとに特定の言語の結果のみが必要であり、この場合は非常に高速である場合にのみ役立ちます。