0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PostgreSQLのjsonb型のlike検索でインデックスを効かせたい

Last updated at Posted at 2025-10-03

やりたいこと

PostgreSQLのjsonb型の各キーにある値をlike検索でインデックス効かせたい

調査

現状、上記を「設定1発でOK」といったやり方はなさそう…
ですのでやや強引に以下で実施

方法

jsonb型カラムと同期できるテキスト型カラムを追加し、テキスト型カラムにインデックス設定して検索

注)キー名と検索したい値が被ってると、よけいなレコードも取得しまうので
多少のノイズが検索結果にあっても問題なければ利用できます

テーブル作成
CREATE TABLE test (
  name jsonb NULL
);
INSERT INTO test (name) VALUES ('{"key1":"あいうえお"}'), ('{"key2":"かきくけこ"}'),('{"key3":"さしすせそ"}');
中身
SELECT * FROM test;
           name
--------------------------
 {"key1": "あいうえお"}
 {"key2": "かきくけこ"}
 {"key3": "さしすせそ"}
当たり前ですが、これだけではインデックス効かせてlike検索できない

EXPLAIN SELECT * FROM test WHERE name::text like '%きく%';
                      QUERY PLAN
------------------------------------------------------
 Seq Scan on test  (cost=0.00..33.80 rows=1 width=32)
   Filter: ((name)::text ~~ '%きく%'::text)
jsonb型カラムのnameをテキスト型にして更新を追従できるname_textカラム追加
ALTER TABLE test ADD COLUMN name_text TEXT GENERATED ALWAYS AS (name::text) STORED;
中身
SELECT * FROM test;
            name             |          name_text
-----------------------------+-----------------------------
 {"key1": "あいうえお"}       | {"key1": "あいうえお"}
 {"key2": "かきくけこ"}       | {"key2": "かきくけこ"}
 {"key3": "さしすせそ"}       | {"key3": "さしすせそ"}
name_textカラムに全文検索のインデックス設定
CREATE INDEX name_text_idx ON test USING gin (name_text gin_bigm_ops);
インデックス確認
\di
Schema |                  Name                   | Type  |   Owner    |            Table
public | name_text_idx                           | index | abcdetg123 | test
インデックス効かせたlike検索できるようになる
EXPLAIN SELECT * FROM test WHERE name_text like '%きく%';

※レコード数がすくないとスキャンになってしまいますが、数万件などに増やすとおそらく
 インデックスを効かせた検索になると思います!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?