PostgreSQLのJITは「諸刃の剣」? 実務でハマらないためのチューニング術
現場でPostgreSQLをいじっていると、一度は遭遇しませんか? 「普段は爆速なのに、複雑なクエリを投げた瞬間にCPU使用率が跳ね上がって、なぜかレスポンスが鈍くなる」という現象。
その犯人、実はJIT(Just-In-Time)コンパイルかもしれません。
PostgreSQL 11から導入されたJITコンパイルは、本来、複雑なクエリの実行を高速化するための強力な武器です。しかし、小〜中規模のクエリに対して無闇に発動させると、コンパイルそのもののオーバーヘッドが実行時間を上回ってしまう。いわゆる「本末転倒」な事態が起きるんです。
今日は、このJITとどう付き合っていくか、実務で使えるチューニングの勘所を共有しますね。
—
JITがなぜ「重く」なるのか
JITコンパイルは、クエリ実行時にLLVMを使ってマシンコードを生成し、実行を最適化します。これ、理論上は素晴らしいんです。でも、コードを生成するのには「コスト」がかかります。
もし、そのクエリがコンマ数秒で終わるようなものだったらどうでしょう?
「実行」する時間よりも「コンパイル」する時間の方が長ければ、ユーザーを待たせる時間は増える一方ですよね。これが、JITが原因で遅延するクエリの正体です。
チューニングの主役はこの3つ
PostgreSQLの設定ファイル(`postgresql.conf`)にいる、以下のパラメータを覚えておいてください。これがJITをコントロールする「蛇口」です。
- `jit_above_cost`
- デフォルト: 100000
- JITを有効にするための最小クエリコスト。これを超えたクエリにのみJITが適用されます。
- `jit_inline_above_cost`
- デフォルト: 500000
- インライン展開(関数呼び出しを減らして最適化すること)を行うコストの閾値。
- `jit_optimize_above_cost`
- デフォルト: 500000
- 最適化処理をガッツリ行うかどうかの閾値。
—
「とりあえず」の調整法:まずはここから
もし、「うちのDB、JITが余計なことをしてそうで怖い」と感じているなら、まずは `jit_above_cost` を少しずつ上げて様子を見るのが定石です。
例えば、今の設定が10万(デフォルト)だとして、これを20万、30万と上げていく。
— セッション単位で試すなら、まずはこれで確認
SET jit_above_cost = 200000;
どうやって判断するか?
一番確実なのは、`EXPLAIN ANALYZE` を叩くことです。
EXPLAIN (ANALYZE, BUFFERS) SELECT … (重いクエリ);
結果の最後に「JIT: enabled」と出ていて、その後の「JIT全実行時間」が目に見えて大きいようなら、そのクエリにはJITが足かせになっています。もしコストがデフォルトの閾値ギリギリであれば、`jit_above_cost` を上げることでJITを回避し、結果として全体のレスポンスが向上することがあります。
—
現場の先輩からのアドバイス
実務で私がいつも意識しているのは、以下の2点です。
1. 「JITは複雑な分析クエリのためのもの」と割り切る
OLTP(トランザクション系)が中心のDBなら、無理にJITを有効にする必要はありません。むしろ、`jit = off` にして完全に無効化してしまった方が、CPUの負荷が安定することもあります。逆に、データ分析やバッチ処理が重いなら、あえて閾値を下げてJITの恩恵をフルに受けるべきです。
2. 全体設定をいじる前に、まずはクエリを見直す
JITが発動するほど「コストが高い」ということは、そもそもインデックスが効いていないか、実行計画が最適化されていない可能性が高いです。まずは `EXPLAIN` のプランを見て、「全スキャンしてないか?」「結合条件は正しいか?」を確認するのが先決。JITのチューニングは、その後の最後のスパイスです。
—
まとめ:結局どうすればいい?
- 普段のクエリが速いなら: そのままのデフォルトでOK。
- 特定の重いクエリでCPUが張り付くなら: `jit_above_cost` を上げて、JITの発動頻度を抑える。
- 分析環境で遅いなら: `jit_above_cost` を下げて、最適化を促進する。
JITは「魔法の杖」ではありません。DBの性格と、実行するクエリの性質に合わせて、チューニングの蛇口を回す。これができると、PostgreSQLとの距離がぐっと縮まりますよ。
もし「設定を変えても状況が変わらない」とか「プランが不安定だ」なんて悩みがあれば、ぜひまた相談してください。データベースの深淵を一緒に覗き込みましょう!
コメント