「なぜか遅い……」を解決する!PostgreSQLの実行計画と上手な付き合い方
こんにちは!データベースの世界に足を踏み入れたばかりのみなさん、日々のお仕事や学習、お疲れ様です。
データベースを使っていると、最初はサクサク動いていたはずのクエリが、データが増えるにつれて「あれ、なんか急に遅くなった?」と感じること、ありますよね。そんな時、エンジニアの先輩たちは「実行計画を見てみよう」なんて言いますが、その結果を見てもチンプンカンプン……なんて経験、誰しも一度はあるはずです。
今日は、そんな皆さんのために「PostgreSQLがなぜそのルートを選んだのか」、そして「どうすれば最短ルートを走ってくれるのか」という、ちょっとした裏技についてお話ししますね。
—
「目的地への行き方」を決めるのは誰?
まず、データベースがクエリを実行する時のことを考えてみましょう。目的地(欲しいデータ)にたどり着くために、PostgreSQLは「どの道を通るか(実行計画)」を自分で一生懸命考えています。
例えば、「東京から大阪へ行く」とき、あなたはこう考えますよね。
- 「急いでいるから新幹線にしよう」
- 「安く済ませたいから高速バスかな」
PostgreSQLも同じです。「データがこれだけあるなら、このインデックス(近道)を使った方が速いよね」と計算しているんです。でも、たまにこの判断が「空気を読めない」時があるんです。道が混んでいるのに、わざわざ狭い裏道を選んだりして、結果的にすごく遅くなってしまう。
他のデータベース製品には「ここを通れ!」と強制的に指示する「ヒント句」という便利な機能があるのですが、PostgreSQLは少し頑固で、標準ではそれに対応していません。
「じゃあ、PostgreSQLではどうしようもないの?」いえいえ、そんなことはありません。いくつか、賢い付き合い方があるんです。
—
方法1:統計情報を「正しく」教えてあげる
PostgreSQLが変なルートを選ぶ最大の理由は、「道の混雑状況を勘違いしている」からです。
データベースの中には「このテーブルにはこれくらいデータがあるよ」という情報(統計情報)が記録されています。ここが古いままだったり、極端な偏りがあったりすると、PostgreSQLは「あ、この道は空いてるはずだ!」と勘違いして、渋滞するルートを選んでしまうんです。
そんな時は、深呼吸してこう言ってあげましょう。
`ANALYZE テーブル名;`
これだけで、「もう一度状況を確認して!」と最新の状況を教えてあげることができます。これだけで劇的に速くなることも多いんですよ。まずはここから試すのが基本です。
—
方法2:それでもダメなら「pg_hint_plan」という助っ人を呼ぶ
どうしてもPostgreSQLが頑固で、「いや、俺はこの道を通るんだ!」と譲らない時。そんな時は「pg_hint_plan」という外部の拡張機能を使う手があります。
これは、まさに「ヒント句」そのものです。クエリの中に、こっそり注釈のように「ここを通ってね」と書き込むことができます。
- 良い点: 明確に動きを固定できるので、トラブルが起きた時に安心感がある。
- 注意点: 拡張機能をインストールする必要がある。あと、あまり多用すると、データベースの賢い判断力を奪ってしまうので、「最終手段」として使うのが大人のたしなみです。
—
大切なのは「問いかけ」を変えること
最後に、少しだけプロの視点を。
実は、実行計画が遅いのは、データベースが悪いのではなく、私たちが書いた「問いかけ方(クエリ)」に隙があるからかもしれません。
- 「すべてのカラムをとりあえず取ってくる」より、「本当に必要なカラムだけを書く」
- 「複雑な計算を一度にやらせる」より、「一度中間テーブルに整理する」
人間だって、早口で難解な質問をされたら混乱しますよね。PostgreSQLも同じです。クエリを少し整理してあげるだけで、驚くほどスムーズに走ってくれるようになります。
—
最後に:楽しんでチューニングしよう!
データベースのチューニングは、慣れないうちは難しく感じるかもしれません。でも、自分の書いたクエリがスッと返ってくるようになった時の快感は、エンジニアとして格別なものですよ。
焦らず、まずは統計情報を整理することから始めてみてくださいね。もし行き詰まったら、いつでもまたこのブログを覗きに来てください。
それでは、良いデータベースライフを!
コメント