【入門編】 部分インデックス(Partial Index) – PostgreSQL

こんにちは!データベースの世界へようこそ。
普段、PostgreSQLを触っていると、「インデックス(索引)」という言葉を嫌というほど耳にしますよね。「とりあえずテーブルの主要な列にインデックスを貼っておけば速くなる!」……なんて考えていませんか?

もちろん間違いではないのですが、インデックスにも「重さ」というコストがあります。今日は、そんなインデックスの概念を少しだけスマートにする、「部分インデックス(Partial Index)」というテクニックを紹介しますね。

—

本棚で例えてみよう

想像してみてください。あなたは、ものすごく膨大な数の本が並ぶ図書館の司書さんです。
利用者が「〇〇というタイトルの本はどこ?」と聞いてきたとき、すべての本を並べ替えた巨大なリスト(インデックス)を全部確認するのは大変ですよね。

そこで、あなたはこう考えました。
「よく借りられるのは『貸出中ではない本』だけだな。それなら、『貸出中の本』のことは無視して、『貸出可能な本』だけのリストを作ればいいんじゃない?」

これが「部分インデックス」の考え方です。

部分インデックスの何がすごいの?

通常、インデックスはテーブルの「すべての行」を対象に作ります。でも、もしあなたのアプリで「未処理のタスクだけを常に検索する」という動作がメインなら、わざわざ「完了済みのタスク」までインデックスに含める必要はありませんよね。

部分インデックスを使うと、こんな嬉しいことが待っています。

  • インデックスがスリムになる!

対象データが絞られるので、インデックスのサイズが驚くほど小さくなります。メモリに乗りやすくなるので、検索スピードも向上します。

  • 更新の負荷が減る!

「完了済みのデータ」が更新されても、インデックスには影響しないので、データベースが頑張らなくて済みます。

  • ストレージの節約!

無駄なデータを保存しないので、ディスク容量も節約できます。

実際に書いてみよう

例えば、`orders`(注文)テーブルがあって、`status`カラムには「注文済み」「発送済み」「キャンセル」が入っているとします。この中で、一番頻繁に検索されるのは「まだ発送されていない注文(status = ‘pending’)」ですよね。

普通にインデックスを作るとこうなります:
`CREATE INDEX idx_orders_all ON orders (order_date);`
(これだと、発送済みの分まで全部インデックスされちゃいます)

でも、部分インデックスならこう書けます:

CREATE INDEX idx_orders_pending
ON orders (order_date)
WHERE status = ‘pending’;

たったこれだけです。`WHERE`句を付けるだけで、「あ、このインデックスは『pending』のやつだけ覚えとけばいいのね!」とPostgreSQLが理解してくれるんです。すごく賢いですよね。

注意点も忘れずに

魔法のような部分インデックスですが、一つだけ注意が必要です。それは、「検索条件とインデックスの条件が一致していないと使われない」ということです。

例えば、`status = ‘shipped’`(発送済み)のデータを検索したいときに、先ほどのインデックスは役に立ちません。PostgreSQLは「あ、これ『pending』用だから、今回は使えないや」と判断して無視します。

「よく使う検索条件」が決まっている時にこそ、このテクニックは最大の輝きを放ちます。

—

最後に:データベースにも「断捨離」を

データベースのチューニングというと、「とにかく速くする」ことに目が行きがちですが、実は「無駄を省く」ことこそが、システムを長く健康に保つコツだったりします。

「このインデックス、本当に全部の行を記録する必要あるかな?」

そんなふうに立ち止まって考えてみたとき、部分インデックスはあなたの心強い味方になってくれるはずです。ぜひ、今動かしているプロジェクトのテーブルで、試せそうなところがないか眺めてみてくださいね。

それでは、また次回の記事でお会いしましょう!Happy Querying!

コメント

タイトルとURLをコピーしました