【入門編】 関数ベースのインデックス(Expression Index) – PostgreSQL

みなさん、こんにちは!データベースエンジニアの現場で日々奮闘している、ブログの管理人です。

今日は、PostgreSQLのちょっと「裏技」っぽいけれど、実はめちゃくちゃ実用的な機能についてお話ししたいと思います。その名も「関数ベースのインデックス(Expression Index)」。

名前を聞くと「うわ、難しそう……」って身構えてしまうかもしれませんが、大丈夫。実はこれ、私たちの日常生活にある「ある工夫」と同じ考え方なんです。

—

「辞書」で例えると分かりやすいかも?

想像してみてください。あなたは今、分厚い辞書の中からある単語を探そうとしています。

普通、辞書は「アルファベット順」に並んでいますよね。だから「Apple」を探すのは簡単です。でも、もしあなたが「大文字・小文字を気にせず、とにかく『apple』という単語を探したい」と思ったとき、どうしますか?

辞書の中に「APPLE」も「apple」も「Apple」もバラバラに載っていたら、結局全部のページをめくって探さないといけませんよね。これ、データベースの世界でも同じことが起きています。

もし、「辞書の横に、すべてを小文字に変換した『検索用インデックス』を別に作っておく」としたらどうでしょう?

そうすれば、辞書本体をいじらなくても、そのインデックスを見るだけで「あ、ここにあるな!」と一瞬で見つけられますよね。これが、PostgreSQLの「関数ベースのインデックス」の正体です。

—

なぜこれが「最強の時短術」なのか

普段、私たちがデータベースを検索するとき、こんな書き方をすることがあります。

SELECT FROM users WHERE lower(email) = ‘taro@example.com’;

この `lower(email)` というのは、「メールアドレスを全部小文字にしてから比較してね」という指示です。

データベースは律儀な性格なので、この命令を受けるたびに、「えーっと、まず全データのメールアドレスを小文字に変換して……それから比較して……」と、毎回一生懸命計算してくれます。データが数百万件あったら、これだけでかなりの時間がかかってしまいますよね。

ここで登場するのが関数ベースのインデックスです。

CREATE INDEX idx_users_lower_email ON users (lower(email));

こうやってあらかじめ「小文字にした結果」をインデックスとして保存しておけば、データベースは検索のたびに計算しなくて済みます。「インデックス帳の中に、計算済みの答えが書いてあるから、それを見ればいいや!」となるわけです。

—

こんな時に使うと効果テキメン!

このワザは、特にこんなシーンで力を発揮します。

  • 大文字・小文字を無視して検索したい時: `lower(col)`
  • JSONデータの中身の一部を頻繁に検索する時: `jsonb_extract_path(data, ‘user_id’)`
  • 日付データから「年」や「月」だけを抽出して集計したい時: `extract(year from created_at)`

これらを使うと、今まで「重いな〜」と思っていたクエリが、まるで魔法のように爆速になることがあります。

—

最後に、ちょっとだけ注意点

ここまで聞くと「じゃあ何でもかんでもインデックスにしちゃおう!」と思うかもしれませんが、そこは少しだけ注意してくださいね。

インデックスは「便利だけど、増えすぎると重くなる」という弱点があります。辞書に付箋をペタペタ貼りすぎると、逆に辞書自体が分厚くなって扱いづらくなりますよね。それと同じで、「本当によく検索する条件」に対してだけ、ピンポイントで作るのが、データベースエンジニアとしての腕の見せ所です。

—

いかがでしたか?

「関数ベースのインデックス」は、ちょっとした工夫でシステムの速度を劇的に改善できる、頼もしい相棒です。もし皆さんのデータベースで「この検索、なんだかいつも時間がかかるんだよな……」という箇所があれば、ぜひ一度試してみてくださいね。

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

コメント

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