そのSQL、実は「書き換え」られている?PostgreSQLのクエリ書き換えエンジンの深淵へ
「なぜか自分の書いたSQLより、PostgreSQLが選んだ実行計画の方が速い」
エンジニアとして経験を積んでくると、一度はこんな感覚に陥りませんか? データベースのチューニングをしていると、どうしても「インデックスをどう貼るか」「統計情報をどう更新するか」といった実行計画(Query Planner)の話ばかりに目が行きがちです。
でも、実はその一歩手前。「パーサが構文を理解した後、プランナーが計画を立てるまでの間」に、PostgreSQLは非常に賢い「書き換え」を行っているんです。今日は、この縁の下の力持ちである「クエリ書き換えエンジン(Query Rewriter)」について、現場の視点からお話ししましょう。
—
1. なぜ「書き換え」が必要なのか?
SQLを投げると、PostgreSQLはまず「パーサ」が構文チェックを行い、次に「クエリツリー」という内部表現に変換します。しかし、この段階のクエリは、まだ「人間が書いたまま」の、いわば素の状態です。
例えば、`VIEW` を使っているとき。PostgreSQLはビューの定義をいちいち物理テーブルに戻して処理しているわけではありません。実は、クエリツリーそのものを改変して、あたかも最初から実テーブルを叩いているかのようなクエリにすり替えているんです。
このプロセスこそが「クエリ書き換え」です。これがあるおかげで、私たちは複雑なビューを気兼ねなく作れるし、ルールシステムによる強力な抽象化が可能になっています。
2. 魔法の正体:ルールシステム(Rewrite Rules)
PostgreSQLには「ルールシステム」という強力な機能が備わっています。これこそが書き換えエンジンの心臓部です。
皆さんが `CREATE RULE` を使う機会は少ないかもしれませんが、実は `VIEW` を作るとき、内部ではこのルールが動いています。
具体例:ビューの書き換え
例えば、こんなビューがあるとします。
CREATE VIEW active_users AS
SELECT FROM users WHERE status = ‘active’;
ここで `SELECT FROM active_users WHERE id = 1;` というクエリを投げると、Rewriterは以下のようにツリーを書き換えます。
- 元: `SELECT FROM active_users WHERE id = 1`
- 書き換え後: `SELECT FROM users WHERE status = ‘active’ AND id = 1`
こうすることで、プランナーは「`active_users` という得体の知れない存在」ではなく、「`users` テーブルに対する最適化」を直接考えられるようになる。これ、凄くないですか?
3. 実務で知っておくべき「落とし穴」
この仕組みを理解していると、現場のトラブルシューティングで一歩先を行けます。
(1)「書き換え」によるパフォーマンスの劣化
ルールによる展開は非常に便利ですが、複雑すぎるルールや深い階層のビューを重ねると、Rewriterが生成するクエリツリーが巨大化します。たまに「単純なSQLなのに実行計画作成(Planning)にやたら時間がかかる」というケースがありますが、原因の一つはこれです。
アドバイス: 階層が深すぎるビューや、複雑なUNION ALLを含むビューは、プランナーが最適化の糸口を見失う原因になります。過度な抽象化には注意してください。
(2)INSERT/UPDATE時の「条件付きルール」
`ON INSERT DO INSTEAD` のようなルールを使うと、書き込みの動作を完全に別物にすり替えられます。これを使えば「論理削除」を透過的に扱うこともできますが、デバッグが地獄になります。
「なぜかデータが入らない」「別のテーブルに値が飛んでいる」という時、真っ先に疑うべきはルールです。`\d+ テーブル名` でルールが定義されていないか、確認する癖をつけておきましょう。
4. 最後に:エンジニアとしての視点
クエリ書き換えエンジンは、PostgreSQLというデータベースが持つ「柔軟性」と「厳密さ」を両立させるための、まさに接着剤のような存在です。
普段意識せずとも動いてくれるものですが、いざという時、この「裏側で何が起きているか」を想像できる力は、あなたのチューニングスキルを一段上のレベルへ引き上げてくれます。
「PostgreSQLは、自分のSQLをどう解釈し、どう『翻訳』したのか?」
そう思ったら、`EXPLAIN` を眺めるだけでなく、`log_statement = ‘all’` で出力されるログや、より深い内部構造を覗いてみてください。データベースと会話ができるようになると、エンジニアとしての仕事はもっと面白くなりますよ。
それでは、良いクエリチューニングライフを!
コメント