Hatena::Grouppostgresql

PostgreSQL 雑記 このページをアンテナに追加 RSSフィード

2009-05-14LIKE検索対応インデックス このエントリーを含むブックマーク このエントリーのブックマークコメント

LIKE 検索では、前方一致検索 (LIKE 'foo%') の場合のみ btree インデックスを使うことができます。内部的には % の部分を最小値~最大値に置き換えた範囲検索に展開されるためです。一方、中間一致検索 ('%foo%') や後方一致検索 ('%foo') ではインデックスが使われません。

しかし既に N-gram 検索が可能な textsearch_senna があります。LIKE クエリSennaクエリは書式は違いますが、適当にコンバートすれば LIKE 検索でも Senna インデックスを使えないかと実験してみたのがこちらです。

LIKE を使った SQL を全く変更する必要なくインデックスが使えるようになるため、SQL に手を入れられない or 入れたくないようなアプリケーションの高速化に役立つかと思います。また、Prepared Statement を使うと LIKE 前方一致検索であっても btree インデックスが使われなくなるという制限がありますが、こちらの方式ならば常に Senna インデックスを利用できるはずです。

CREATE INDEX idx_like ON tbl USING senna (t like_ops);
SELECT * FROM tbl WHERE t LIKE '%foo%'; -- it can use index!

注意としては、正規化を行う通常の N-gram 全文検索とは異なる設定でインデックスを構築する必要があるので、正規化検索用と LIKE 検索用のインデックスには互換性はありません。このあたりはもう少し実装を整理する必要がありそうでしょうか。

ところで、8.4 ならば LIKE (~~) 演算子を問題なくサポートすることができたのですが、8.3 やそれ以前のバージョンでは planner が混乱するようで、エラーになってしまいました。8.4 のどの改良と関連しているかは記憶にないのですが、何か他の目的のためにコードが整理されたことの副産物かもしれません。

----

早速反応をいただきました。