0Pricing
SQL Academy · レッスン

GINによるJSONBのインデックス化

JSONBドキュメントにGINインデックスを作成し、jsonb_path_opsで包含検索を高速化します。

「GINによるJSONBのインデックス化」はCoddyKit上の無料SQL Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSQL Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 SQL Academyコースには全4レッスンが含まれています。

JSONBにGINを使う理由

JSONBドキュメントには、多数の「項目」(キーと値の組や配列要素)が含まれます。GIN(Generalised Inverted Index)は、「ドキュメントにXが含まれる行」を検索するクエリに適しています。

デフォルトのGINインデックス

デフォルトの演算子クラスは@>、?、?|、?&に対応します。

CREATE INDEX events_data_gin ON events USING GIN (data);

-- These now use the index:
SELECT * FROM events WHERE data @> '{"type":"login"}';
SELECT * FROM events WHERE data ? 'error';

jsonb_path_ops: より小さく高速

包含だけを行うクエリでは、サイズが半分になり高速です。ただし、対応するのは@>だけです。

CREATE INDEX events_data_gin ON events USING GIN (data jsonb_path_ops);

-- Supports @>
-- Does NOT support ?  ?|  ?&
SELECT * FROM events WHERE data @> '{"type":"login"}';

1つのパスだけをインデックス化する

1つのキーだけを検索する場合は、抽出した値に対する式B-treeインデックスの方がさらに高速です。

CREATE INDEX events_user_id_idx
  ON events (((data->>'user_id')::BIGINT));

SELECT * FROM events WHERE (data->>'user_id')::BIGINT = 42;

配列内部をインデックス化する

配列のパスにGINインデックスを使用します。

CREATE INDEX events_tags_gin
  ON events USING GIN ((data->'tags'));

SELECT * FROM events WHERE data->'tags' @> '["admin"]'::JSONB;

JSONBインデックスと他のフィルタの組み合わせ

複合述語では、JSONB部分にGINインデックスを使い、JSONB以外の部分には別のインデックスを使えます。

EXPLAIN ANALYZE
SELECT * FROM events
WHERE data @> '{"type":"login"}'
  AND ts >= NOW() - INTERVAL '7 days';
-- BitmapAnd: GIN index on data, B-tree on ts

GINの書き込み性能

GINの更新はB-treeより負荷が高くなります。書き込みが非常に多いテーブルでは、fastupdateオプションによってGINの更新を保留リストにまとめ、VACUUMでフラッシュできます。

CREATE INDEX events_data_gin ON events USING GIN (data) WITH (fastupdate = on);

-- Flush manually if needed:
SELECT gin_clean_pending_list('events_data_gin');

インデックスサイズ

JSONBのGINインデックスは大きくなることがあります。巨大なテーブルでは、次の方法を検討してください。

  • 特定のパスだけをインデックス化する(式インデックス)
  • 包含だけを行う場合はjsonb_path_opsに切り替える
  • 更新の多いフィールドを通常の列に分離する

トライグラムとの組み合わせ

JSONB内部であいまいなテキスト検索を行う場合は、TEXT式に抽出してpg_trgmのGINインデックスを追加します。

CREATE INDEX events_message_trgm
  ON events USING GIN ((data->>'message') gin_trgm_ops);

インデックスが役に立たない場合

フィルタがすべての行に当たる場合(選択性が非常に低い場合)、インデックスがあってもプランナーはシーケンシャルスキャンを選ぶことがあります。EXPLAIN ANALYZEで確認してください。

JSONBインデックスのメンテナンス

GINインデックスも他のインデックスと同じように肥大化します。定期的にREINDEX CONCURRENTLYを使用してください。

REINDEX INDEX CONCURRENTLY events_data_gin;

まとめ

GINにより、JSONBのフィルタ検索をミリ秒単位で実行できます。

  • デフォルトのGIN: @>、?、?|、?&
  • jsonb_path_ops: より小さく、包含専用
  • 抽出したスカラー値に対する式B-tree: 1つのキーに対して最速

理解度チェック

JSONB列に対して、常にdata @> ...だけを検索します。すべての機能に対応しつつ、最もサイズが小さくなるインデックスはどれですか。

よくある質問

「GINによるJSONBのインデックス化」レッスンは無料ですか?

はい。「GINによるJSONBのインデックス化」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、SQL Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 SQL Academyコースには全4レッスンが含まれています。

「GINによるJSONBのインデックス化」で何を学びますか?

JSONBドキュメントにGINインデックスを作成し、jsonb_path_opsで包含検索を高速化します。 ブラウザで直接実行するハンズオンコードでSQL Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

SQL Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのSQL Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「GINによるJSONBのインデックス化」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このSQL Academyレッスンでコードを書いて実行できますか?

はい。すべてのSQL Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. JSONBとJSON:使い分け
  2. パス演算子:->、->>、@>
  3. GINによるJSONBのインデックス化
  4. モデリング:JSONBが正規化を上回る場合
← SQL Academyに戻る