こんにちは!データベースの世界にどっぷり浸かっているエンジニアです。
今日は、PostgreSQLのチューニングにおいて「隠れた調整弁」とも言える面白い設定、`join_collapse_limit` についてお話ししようと思います。
「JOINの順番なんて、データベースが勝手に一番いいやつを決めてくれるんじゃないの?」って思いますよね。その通り、基本的にはその考えで正解です。でも、もしテーブルが10個、20個と増えていったら……? データベースも人間と同じで、あまりに選択肢が多すぎると「もうどれが正解かわからないよ!」とパンクしてしまうことがあるんです。
そんな時、この設定がどう役立つのか、一緒に見ていきましょう。
—
料理店で例えるとわかりやすい?
想像してみてください。あなたは今、超有名店のキッチンに立っているシェフです。
そこへ「サラダと、ステーキと、スープと、パスタを全部使って、最高の一皿を作って!」という注文が入りました。
この時、シェフ(=PostgreSQLのプランナ)は、調理の順番を考えます。
「まずはスープを煮込んでからステーキを焼くか? それともパスタを茹でながらサラダを盛り付けるか?」
この組み合わせの数って、食材(=テーブル)が増えれば増えるほど、爆発的に増えていくんです。全部の組み合わせを試していたら、いつまで経っても料理が出てきませんよね。
`join_collapse_limit` は「じっくり考える制限時間」
そこで登場するのが `join_collapse_limit` です。これは、「プランナが結合順序を考える際、何個までのテーブルなら本気で順序を並べ替えて検討するか」という上限を決める設定値です。
- デフォルト値は「8」です。
- もしテーブルが8個以下なら、PostgreSQLは「よし、全部の組み合わせを計算して一番速い順序を見つけるぞ!」と頑張ります。
- 逆にテーブルが8個を超えると、PostgreSQLは「全部は計算しきれないから、ある程度のところで妥協して、効率的な順序を選ぼう」と作戦を変えます。
—
なぜこの数値をいじる必要があるの?
普段の運用では、デフォルトの「8」のままでほとんど問題ありません。でも、たまにこんなことが起きます。
「クエリがすごく複雑で、テーブルを15個くらいJOINしてるんだけど、なぜか異常に遅い……」
そんな時、この数値を少し上げて(例えば12とかに)あげると、プランナが「もう少し広い範囲で順序を検討してみよう」と頑張ってくれるようになり、劇的に実行速度が上がることがあるんです。
逆に、あまりにこの数値を大きくしすぎると、今度は「計算すること自体」に時間がかかってしまい、クエリを実行する前にフリーズしてしまう……なんていう悲劇も起こり得ます。まさにトレードオフですね。
—
調整する時の「鉄則」
もし皆さんが現場でこの設定を触る機会があったら、次のことを覚えておいてください。
1. まずは「インデックス」を疑う
JOINが遅い原因の9割は、この設定の問題ではなく、単に「インデックスが貼られていない」ことであることがほとんどです。まずは `EXPLAIN ANALYZE` を見て、ボトルネックを突き止めるのが先決です。
2. 数値をいじるのは「最後の手段」
`join_collapse_limit` は、いわば劇薬です。安易に全体設定を変えるのではなく、特定のクエリに対して `SET LOCAL join_collapse_limit = …` のようにして、影響範囲を限定して試すのが、ベテランの流儀ですよ。
—
最後に
データベースの設定って、一見すると難しそうな数字が並んでいて嫌になりますよね。でも、「データベースも計算機であり、時には悩みすぎることもある」と考えると、少し親近感が湧きませんか?
「順序を考えすぎて迷走しているプランナに、少しだけヒントを与えてあげる」。そんな気持ちでチューニングに向き合ってみると、意外と楽しいものですよ。
もし皆さんの環境で「このクエリ、なんか動きが怪しいな」と思ったら、一度この設定のことも思い出してみてくださいね。
それでは、また次回の記事でお会いしましょう!Happy Querying!
コメント