【じんいんでっくす】

GINインデックス とは?

最終更新:
💡 要素から該当する行を探す、逆引きの索引

GINインデックスはPostgreSQLの汎用転置インデックス。要素から該当行を探す仕組みで、全文検索・配列・JSONBなどを支えます。対応する演算子、更新コスト、検索計画の確認が重要です。

📌 このページのポイント
GIN:要素から該当する行を逆引き元のタグ配列行1:Python, SQL行2:Python索引の対応(論理的な例)Python行1・行2SQL行1配列・JSONB・全文検索等で利用対応する演算子・式と実際の検索計画を確認
タグ配列の要素から該当行へ逆引きする対応で、内部構造そのものではありません。更新や容量のコストがあり、索引の使用や速度改善を保証するものではありません。
ひよこ ひよこ
GINは普通の索引と何が違うの?
ペンギン先生 ペンギン先生
PostgreSQLで標準のB-treeは等価・範囲検索や並び順などに使えるよ。GINはひとつの値に含まれる要素を取り出し、その要素が現れる行を探す転置インデックスなんだ。役割が違うから、条件に合わせて選ぶよ。
ひよこ ひよこ
逆引きって、どういうこと?
ペンギン先生 ペンギン先生
たとえば「行1にPythonとSQL、行2にPython」というタグ配列があれば、索引側では「Python→行1・行2」「SQL→行1」と対応付けるよ。全文検索でも似た考え方で、tsvectorにした語の要素を扱うんだ。
ひよこ ひよこ
配列やJSONBなら、どんな検索でも速くなる?
ペンギン先生 ペンギン先生
対応する演算子と式が必要だよ。配列の包含なら、tagsがtext[]のとき「tags @> ARRAY['Python']」などが候補。JSONBは既定のjsonb_opsとjsonb_path_opsで対応演算子が異なる。索引の作り方と検索条件を合わせよう。
ひよこ ひよこ
データを更新するときの負担は?
ペンギン先生 ペンギン先生
1行から複数の索引要素を更新するため、追加・更新のコストや索引の容量に注意するよ。fastupdateは更新を一時的な待ちリストへまとめる方式だけど、その掃除や検索への影響もある。書き込みが多いからGiSTへ替えれば必ず解決する、とは言えないんだ。
ひよこ ひよこ
GINを作れば、必ずその索引を使ってくれる?
ペンギン先生 ペンギン先生
必ずではないよ。検索に合う式でも、行数や該当件数などから全体を走査する計画が選ばれることがある。実際の条件とデータでEXPLAINなどを確認し、読み取りの改善と書き込みの負担を比べよう。
もっと詳しく知りたい人へ

jsonb_opsとjsonb_path_opsは何が違う?

既定のjsonb_opsは包含やjsonpath条件に加え、キー存在の?・?|・?&に対応します。jsonb_path_opsは@>・@?・@@に対応し、キー存在演算子には対応しません。単にJSONBだから一方を選ぶのではなく、実際の検索条件に合わせて判断します。

ペンギン
まとめ:ざっくりこれだけ覚えればOK!
「GINインデックス」って出てきたら「データの要素から該当行を逆引きするPostgreSQLの索引」と思えばだいたいOK!
📖 おまけ:英語の意味
「Generalized Inverted Index」 = 汎用転置インデックス
💬 inverted index(転置インデックス)を汎用化(generalized)したものだよ。GINという略語がジンのお酒みたいだけど、中身はかなり高度な技術なんだ

参考資料

← 用語集にもどる