CodeGym /コース /SQL SELF /クエリパフォーマンス分析入門

クエリパフォーマンス分析入門

SQL SELF
レベル 41, レッスン 0
使用可能

ちょっとリアルな話から始めよう。君が大手ネットショップの開発者として働いてると想像してみて。全部バッチリ動いてるんだけど、ひとつだけ問題があるんだ。月次売上レポートがめっちゃ遅くて、ユーザーはレポートが終わる前にもう一回注文できちゃうくらい。君もイライラ、マネージャーもイライラ、PostgreSQLサーバーはケトルみたいに沸騰してて、まるでアポカリプスの予感。もし一発で原因を見つけて直せたら、最高じゃない?

クエリパフォーマンス分析は、PostgreSQLの健康診断みたいなもの。どこが「ボトルネック」(痛みポイント)なのか見つけて、直すことでユーザー体験もシステムリソースも節約できるんだ。

PostgreSQLの中でクエリはどう動いてる?

例えば、こんなシンプルなクエリを書くとする:

SELECT * FROM products WHERE price > 100;

PostgreSQLはいきなりデータを取りに行くわけじゃない。まずクエリを解析して、どうやって実行するのがベストか考えてから、実際に動き出すんだ。

クエリ実行の主なステップ:

  1. パース。PostgreSQLはクエリの構文エラーをチェックして、中間表現に変換する。
  2. 最適化。クエリオプティマイザがいくつかの実行パターンを評価して、一番「コストが安い」(時間やリソース的に)ものを選ぶ。
  3. 実行。サーバーは選ばれたプラン通りにデータを取りに行く。

「ボトルネック」って何?

「ボトルネック」っていうのは、クエリの中で全体を遅くしてる部分のこと。たとえば、PostgreSQLがインデックスを使わずにテーブル全体をスキャン(Seq Scan)しちゃうと、クエリが遅くなる。あるいは、想定よりデータが多くて、サーバーがソートや結合、フィルタリングにめっちゃ時間かかる場合もある。

こういう部分がボトルネック。まずはここを見つけて最適化するのが大事!

クエリパフォーマンス分析のツール

PostgreSQLには、クエリの問題を見つけるための強力なツールがいくつかあるよ:

  1. EXPLAIN と EXPLAIN ANALYZE。 これらのコマンドで、PostgreSQLがクエリをどう実行するつもりか、または実際に実行してどんなパフォーマンスだったかを確認できる。
  • EXPLAIN: クエリを実行せずに実行プランだけ表示する。
  • EXPLAIN ANALYZE: クエリを実際に実行して、リアルな実行プランとタイムメトリクスを表示する。

EXPLAINの使い方例:

EXPLAIN SELECT * FROM products WHERE price > 100;

出力例:

Seq Scan on products  (cost=0.00..35.50 rows=5 width=72)
  Filter: (price > 100)

ここでは「Seq Scan」つまりテーブル全体スキャンになってて、大きなテーブルだと非効率だよ。

  1. pg_stat_statements。 これは追加のエクステンションで、実行されたクエリを記録してくれる。こんなことが分かる:
  • どんなクエリがサーバーで実行されてるか。
  • 各クエリにどれくらい時間がかかってるか。
  • クエリが返す行数やリソース消費量。

pg_stat_statementsを有効にするには:

  1. エクステンションを有効化:
CREATE EXTENSION pg_stat_statements;
  1. PostgreSQLの設定を調整: postgresql.confファイルに以下を追加:
   shared_preload_libraries = 'pg_stat_statements'
   pg_stat_statements.track = all
  1. PostgreSQLを再起動。

これでクエリを分析できるようになる:

SELECT * FROM pg_stat_statements ORDER BY total_time DESC LIMIT 5;

これで「一番重い」クエリ上位5件が、合計実行時間の多い順に表示されるよ。

  1. スロークエリログ。 PostgreSQLに、実行に時間がかかりすぎたクエリ(例えば1秒以上)をログファイルに記録させることもできる。

そのためにはpostgresql.confで:

log_min_duration_statement = 1000  # ミリ秒単位(1秒)

これで遅いクエリがPostgreSQLのログに記録される。

パフォーマンス分析の主なメトリクス

クエリパフォーマンスを分析するときは、次の主要なメトリクスに注目しよう:

  1. 実行時間。クエリの実行にかかった時間。速いほど良い!
  2. 行数。クエリが返す、またはスキャンする行数が想定より多いと問題かも。
  3. インデックス利用。インデックスを使うべきクエリが、シーケンシャルスキャン(Seq Scan)してたら要最適化。
  4. バッファとディスク操作。ディスクアクセスが多いクエリは、メモリからデータを取るクエリより遅い。

これらの知識、どうやって実践する?

例1: 遅いクエリ

100より高い値段の商品を全部取得するクエリを書く:

SELECT * FROM products WHERE price > 100;
クエリが遅いと気づいたら、 EXPLAINを使ってみると:
Seq Scan on products  (cost=0.00..35.50 rows=5 width=72)
  Filter: (price > 100)

問題:priceカラムにインデックスがないから、テーブル全体スキャンになってる。

解決策:

インデックスを作成しよう:

CREATE INDEX idx_price ON products(price);

これでクエリはIndex Scanを使うようになる:

Index Scan using idx_price on products  (cost=0.15..8.25 rows=5 width=72)
  Index Cond: (price > 100)

例2: pg_stat_statementsで遅いクエリを特定

このコマンドで:

SELECT query, total_time, calls
FROM pg_stat_statements
ORDER BY total_time DESC
LIMIT 1;

実行時間がめっちゃ長いクエリを発見。EXPLAIN ANALYZEで詳細を見て、修正したら速くなった!

EXPLAINやpg_stat_statementsなどのツールを使い始めると、クエリがどんどん速くなるし、PostgreSQLサーバーもスイス時計みたいに動くよ。次のレクチャーでは、EXPLAINのcost、rows、widthみたいなパラメータの詳細に突っ込んで、実行プランを本みたいに読めるようになろう!

2
タスク
SQL SELF, レベル 41, レッスン 0
ロック未解除
EXPLAINを使ってクエリ実行プランを分析しよう
EXPLAINを使ってクエリ実行プランを分析しよう
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION