データベースの「断捨離」術!クエリを爆速にする「述語のプッシュダウン」のお話
こんにちは!データベースの世界にどっぷり浸かっているエンジニアです。
皆さんは、何か調べ物をする時に「とりあえず全部の資料を机に広げてから、必要なものを探す」なんてこと、やっていませんか?実はこれ、データベースの世界でも同じことが起きていて、パフォーマンスが落ちる大きな原因の一つなんです。
今日は、PostgreSQLが裏側でこっそり行っている「賢い仕分け術」、「述語(じゅつご)のプッシュダウン」について、専門用語を極力使わずに解説してみたいと思います。
—
想像してみてください:図書館の検索係
あなたが大きな図書館の検索係だとしましょう。誰かから「2023年に出版された、料理のレシピ本を探して!」と頼まれました。
さて、あなたならどう動きますか?
1. 非効率なやり方: 図書館にある何十万冊という本を、端から端まで全部台車に積んで、自分のデスクまで持ってくる。そのあとで、「あ、これは2023年じゃないな」「これは料理じゃないな」と1冊ずつチェックする。
2. 賢いやり方: 書架に向かう前に、「2023年出版」「料理」という条件をメモしておく。そして、本棚の列を回る時に、その条件に合わない本はそもそも台車に乗せない。
後者のほうが、圧倒的に楽ですよね。「述語のプッシュダウン」とは、まさにこの「書架に行く前に条件で絞り込む」という賢い動きのことなんです。
「プッシュダウン」って何をしているの?
データベースで言う「述語」というのは、簡単にいえば「WHERE句で指定した条件(これとこれが一致するもの、とか)」のことです。
通常、データベースは私たちが書いたSQLを読み解く時、なるべく仕事をサボろうとします(いい意味で!)。
- 「全部のデータを一旦持ってきてから、あとで選別しよう」とするよりも、
- 「データを読み込む(スキャンする)その瞬間に、条件に合うものだけを拾い上げよう」とするほうが、メモリの消費も少ないし、処理も速いですよね。
この「条件をできるだけ深いところ(データの入り口)まで押し下げる」という動きが、名前の由来です。
私たちが意識すべき「たった一つのこと」
「じゃあ、この最適化はPostgreSQLが勝手にやってくれるなら、私たちは何もしなくていいの?」と思うかもしれません。
半分正解で、半分間違いです。PostgreSQLのオプティマイザ(賢い司令塔)はとても優秀ですが、「人間が条件を複雑にしすぎると、プッシュダウンがうまく効かなくなる」ことがあります。
例えば、こんな書き方をすると、データベースは少し混乱してしまいます。
— 少しもったいない書き方
SELECT FROM (
SELECT FROM users
) AS sub
WHERE sub.age > 20;
これだと、一度すべてのデータをサブクエリという「別の箱」に詰め込んでから、あとで条件判断をしようとしてしまうことがあります。
— こう書くほうが、データベースは迷いません!
SELECT FROM users
WHERE age > 20;
データベースにとって、「何が条件なのか」をシンプルに伝えてあげること。これが、クエリを速くするための第一歩なんです。
まとめ:データベースと「おしゃべり」しよう
「述語のプッシュダウン」なんて難しそうな名前ですが、要は「探す前に、何が必要かをハッキリ伝える」という、私たちの日常の探し物と同じなんですね。
もし、今動かしているクエリが少し遅いなと感じたら、ぜひ一度`EXPLAIN`コマンドを使って、PostgreSQLがどんな作戦を立てているのか覗いてみてください。
「あ、ここでちゃんと絞り込めていないのかも?」と気づくだけで、あなたの書くSQLは一段上のレベルに進化しますよ。
データベースを「速く動かす」って、なんだか料理の時短テクニックみたいで楽しくないですか?ぜひ、皆さんも自分なりの最適化のコツを見つけてみてくださいね!
それでは、また次回の記事でお会いしましょう!
コメント