DBチューニング / スロークエリ改善の4ステップ¶
原文¶
エンジニアは全員、DBチューニング/ スロークエリ改善のやり方を知った方がいい。特にスロークエリは改善できないと画面が重くなり、パフォーマンスからユーザー体験まで諸々激落ち。離脱/ 解約までつながってしまうからだ。
スロークエリー改善では概ね以下の1~4に従う。 1. 計測 → 2. 実行計画 → 3. 改善 → 4. 確認
1. 計測 重いクエリーの具体的箇所を特定する。ボトルネック(時間がかかりすぎ)なAPIを特定 → その中で使われているクエリーのうちボトルネックになっているクエリー(スロークエリー)を特定。1s以上かかっているものがあれば直すべき。MySQL, PostgreSQL等、各主要DBでスロークエリ一覧を洗い出す機能がある。
2. 実行計画 SQLのEXPLAINコマンドを使ってクエリの実行計画を読み取って改善策を見出す。最も遅くなるのが、フルスキャンと呼ばれるインデックスが何もなく全データをスキャンしているような状態。あるあるだと、意図したインデックスが使われていないこと。大規模開発だと連携失敗で改善されて速くなったクエリが実は使われてなかったなんてこともある。実行計画パートは経験が物を言うので実践あるのみ。
3. 改善 2の実行計画の結果からわかった改善策を実施。インデックスの付け足し、張り替えからクエリの書き換えまで、効果が一番大きそうなところから順にやる。施策前後でどうなったか、どれくらい速くなったかちゃんと記録を残す。
4. 確認 実際にクラウド/オンプレで動くDBサーバーにアプライして、本当に速くなっているかを確認。
要約¶
スロークエリ改善は「計測 → EXPLAIN → 改善 → 確認」の4フェーズ。まず1秒以上かかるクエリを特定し、EXPLAINでフルスキャンや未使用インデックスを見つけ、インデックス追加やSQL書き換えで改善し、本番環境で効果を確認する。ローカルでなく本番環境で効果確認まで行うのが肝。
解説¶
各ステップの具体的ツール¶
計測
- MySQL: slow_query_log + long_query_time設定、performance_schema
- PostgreSQL: log_min_duration_statement、pg_stat_statements
- APM: Datadog APM、New Relic、Sentry Performance で API→クエリの紐付け
実行計画(EXPLAIN)
- MySQL: EXPLAIN ANALYZE、EXPLAIN FORMAT=JSON
- PostgreSQL: EXPLAIN (ANALYZE, BUFFERS)
- 読むべきポイント: type (ALL = フルスキャン要注意)、rows、key (使ってるインデックス)
改善パターン | 原因 | 対応 | | --- | --- | | フルスキャン | WHERE/JOIN条件のカラムにインデックス追加 | | 意図しないインデックス | ヒント句 or クエリ書き換え | | N+1 | JOINまたはプリロード | | 大きなソート | インデックス順序の活用、LIMIT | | 不要JOIN | スキーマ設計見直し |
確認 - ローカルと本番ではデータ量・分散・キャッシュ状態が違うため、本番(またはステージング)での確認が必須 - 施策前後のクエリ実行時間・APIレスポンスタイムを記録
→ 関連: DBクエリ最適化、APIレイテンシ改善手札