Hatena::ブログ(Diary)

青空を探す、旅の記録。 Twitter

カケラの樹

2015/12/22 Tue

PGroongaのインデックスを常に使う方法。

| 18:35

PGroongaJSON(B)に対しても全文検索できるのが便利ですが、レコード数が少ないとこんな感じで困ったことになる。

チュートリアルにあるサンプルスキーマデータを投入した状態で、

test=# SELECT record FROM logs WHERE record @@ 'paths @ ".code" && number >= 200 && number < 300';
ERROR:  pgroonga: operator @@ is available only in index scans

レコード数が少ないので全件舐めたほうが速いからプランナがインデックスを使おうとせずにこうなる。

test=# explain SELECT record FROM logs WHERE record @@ 'paths @ ".code" && number >= 200 && number < 300';
                                   QUERY PLAN                                   
--------------------------------------------------------------------------------
 Seq Scan on logs  (cost=0.00..26.38 rows=655 width=32)
   Filter: (record @@ 'paths @ ".code" && number >= 200 && number < 300'::text)
(2 rows)

チュートリアルにあるとおり、

SET enable_seqscan = off;

すれば動くけど、本番でこれやるのはちょっとどうかと。かと言って、レコード数が増えてきてからPGroongaを使うようにアプリケーションを改修するっていうのも乗り気がしない。最初から@@演算子を使ったクエリを書きたい。


ってことでどうするか。要は常にインデックスを使うようにすればいいので、pg_hint_planを使う。

インストールした上で、クエリにヒント句を足してやるだけ。

test=# /*+ IndexScan(logs) */ SELECT record FROM logs WHERE record @@ 'paths @ ".code" && number >= 200 && number < 300';

record                                            
----------------------------------------------------------------------------------------------
 {"code": 200, "host": "www.example.com", "tags": ["web", "example.com"], "message": "GET /"}
(1 row)

これでレコードが1つしかなかろうが常にインデックス使用され、@@演算子を使ったクエリが常に通るようになる。

トラックバック - http://d.hatena.ne.jp/yune_kotomi/20151222/1450776904