「それ、実行する意味ある?」PostgreSQLの定数畳み込みを使いこなす
エンジニアの皆さん、お疲れ様です。
日々クエリのパフォーマンスと格闘していると、「なぜPostgreSQLはこんなに賢いのか?」と驚かされる瞬間がありますよね。特に、複雑な計算式をクエリに書いても、なぜか一瞬で結果が返ってくる……そんな経験はないでしょうか。
今日は、そんなPostgreSQLの「縁の下の力持ち」とも言える最適化機能、「定数畳み込み(Constant Folding)」についてお話しします。これを知っておくと、クエリの可読性を保ちつつ、パフォーマンスを損なわないための「ちょっとしたコツ」が見えてきます。
定数畳み込みって、結局なに?
一言で言えば、「実行時に計算しなくてもいいものは、コンパイル(計画作成)の段階で計算しちゃえ!」という最適化です。
例えば、コードの中に `1 + 1` と書かれていたら、わざわざ実行時に足し算をさせる必要はありませんよね? 最初から `2` として扱えばいい。これをクエリの世界でやっているのが定数畳み込みです。
具体例を見てみましょう。こんなクエリを投げたとします。
SELECT FROM orders
WHERE created_at > (CURRENT_DATE – INTERVAL ‘1 day’);
厳密には `CURRENT_DATE` はクエリ実行時に評価されるため完全な定数ではありませんが、PostgreSQLのクエリオプティマイザは、リテラル同士の演算を賢く処理します。
もし、こんなクエリを書いてしまったらどうなるでしょうか?
SELECT FROM sales
WHERE amount > (1000 1.08 12);
人間が読むには「単価 × 税率 × 期間」と書いてある方が親切ですよね。でも、PostgreSQLはこれを実行プランを作る段階で、`12960` という計算済みの数値に置き換えてから実行します。つまり、クエリの可読性と実行速度のトレードオフを、データベース側が自動的に解消してくれているんです。
なぜこれが重要なの?
「計算くらい、CPUが一瞬でやってくれるんじゃないの?」と思うかもしれません。確かにそうですが、重要なのは「インデックスの効き」です。
もし複雑な式をそのままクエリに残し、それが定数畳み込みできないような「非安定(Volatile)な関数」を含んでいると、PostgreSQLはインデックスを無視してフルスキャンを始めることがあります。
例えば、ユーザー定義関数を使って計算している場合、PostgreSQLはその関数が毎回違う値を返すかもしれないと警戒します。定数畳み込みが効くのは、基本的に「結果が常に同じ(Immutable)」であるとデータベースが確信できる場合に限られます。
実践:最適化を味方につけるテクニック
実務で意識すべきは、「オプティマイザに定数だと確信させること」です。
1. Immutable関数を味方にする
自分で関数を作る際、計算結果が変わらないのであれば `IMMUTABLE` 属性を必ず付けましょう。
CREATE OR REPLACE FUNCTION calculate_tax(price numeric)
RETURNS numeric AS $$
BEGIN
RETURN price 1.1;
END;
$$ LANGUAGE plpgsql IMMUTABLE; — これが重要!
これだけで、PostgreSQLはこの関数を「定数」として扱い、クエリ内で定数畳み込みの対象にしてくれます。
2. EXPLAIN ANALYZEで確認する
自分が書いたクエリがどう解釈されているか、不安なら `EXPLAIN` を見てみましょう。
EXPLAIN SELECT FROM sales WHERE amount > (1000 1.08);
結果の中に `Filter: (amount > 1080::numeric)` のように、計算済みの値が出てくれば成功です。もし計算式がそのまま残っているようなら、オプティマイザがそれを定数と見なせていないサインかもしれません。
最後に:エンジニアとしての心得
定数畳み込みは非常に便利ですが、「何でもかんでもDBで計算させればいい」というわけではありません。
複雑すぎるビジネスロジックをSQLの式に詰め込むと、コードの意図が読みづらくなりますし、将来的なメンテナンスコストも跳ね上がります。
- 定数として事前に計算できるものは、アプリケーション側で計算してからクエリに投げる
- SQLで書く必要があるなら、可読性を優先し、PostgreSQLの最適化能力を信じる
このバランス感覚こそが、優れたデータベースエンジニアの証です。「機械に任せられることは任せ、人間にしかできない設計や可読性の確保に頭を使う」。そうすれば、システムもコードも、驚くほど美しく保てるはずですよ。
それでは、また現場でお会いしましょう!
コメント