先に要点
- チューニングの鉄則は「安くて効果の大きい順」に手を打つこと。いきなりサーバー増強やキャッシュに飛ばず、SQL → 索引 → 最後にキャッシュの順で考えます。
- 大原則は「まず測る」。推測でいじらず、実行計画(EXPLAIN)とスロークエリログで「どのクエリが・なぜ遅いか」を特定してから直します。
- 最初に疑うのはSQLと呼び出し側のプログラム。N+1問題(ループで大量に発行)や取りすぎ(SELECT *・不要な行/列)は、索引より先に潰すべき定番です。
- 次の最大のレバーが索引(インデックス)。WHERE・JOIN・ORDER BYで使う列に適切に付けると劇的に速くなります。ただし付けすぎは書き込みを遅くします。
- それでも足りないときの最後の手段が、非正規化・マテリアライズドビューやサマリーテーブル、Redis などのキャッシュ。これらは複雑さと引き換えなので順番を守ります。
DBが遅い。とりあえずサーバーを強くすればいい? ── これはよくある遠回りです。DBのパフォーマンス改善には「安くて効果の大きい順」という定石があり、その順番を守るだけで、多くの場合お金をかけずに大きく速くできます。
この記事では、MySQL・PostgreSQL・Oracle などに共通するチューニングの基礎を、測る → SQL/プログラム → 索引 → 最後にキャッシュという順序で整理します。個別の製品コマンドより、どの順で何を疑うかという考え方に重点を置きます。
大原則:まず「測る」(推測でいじらない)
チューニングで最もやってはいけないのが「たぶんここが遅い」で当てずっぽうに直すことです。まず事実を掴みます。
実行計画(EXPLAIN)
そのSQLをDBがどう処理するつもりかを見る。全件走査(フルスキャン)か索引を使うか、どの順でJOINするかが分かる。MySQL/PostgreSQL/Oracleいずれにも同種の機能がある。
スロークエリログ
実際に遅かったクエリを記録する仕組み。「どのクエリが・何回・どれだけ遅いか」を集計し、影響の大きいものから手を付ける。
原則は「一番遅い/一番回数の多いクエリから直す」。数ミリ秒のクエリを詰めるより、1本の重いクエリや、大量に呼ばれるクエリを直す方が、効果は桁違いです。
① まずSQLと呼び出し側プログラムを疑う(索引より先)
意外に思われますが、索引を足す前に「そもそもSQLと使い方が無駄をしていないか」を先に見ます。ここが原因なら、索引をいくら足しても解決しないからです。
N+1問題(最頻出)
一覧を1回引いた後、各行ごとにループで追加クエリを発行してしまう典型。100件なら1+100回。JOINやまとめ取得(IN句)で1〜数回に減らす。ORM使用時に特に起きやすい。
取りすぎ(over-fetching)
SELECT * で全列、必要な数行だけでいいのに全件取得——など。必要な列・行だけにし、件数は LIMIT で絞る。転送量と処理が減る。
索引が効かない書き方
WHERE句で列を加工する(WHERE YEAR(created_at)=2026 など)と索引が使えない。列はそのまま、値側を加工する形に直す。先頭ワイルドカードの LIKE '%foo' も効きにくい。
重いページング
OFFSET が大きいページングは、内部で大量の行を読み飛ばすため深いページほど遅い。キー基準(前回の最後のIDより大きい、等)のページングに変えると安定する。
アプリのループの中でクエリを叩いていないか——これはチューニングで最初に確認すべき点です。データベース単体を眺めても気づきにくく、呼び出し側のコードを見て初めて分かります。
② 索引(インデックス)を付ける
SQLと使い方を整えたら、次の最大のレバーが索引です。索引は本の巻末索引と同じで、全ページ(全行)を読まずに目的の行へ直行できるようにします。
索引を付ける基本
- WHERE・JOIN・ORDER BY で使う列が第一候補。ここが全件走査になっていると遅い。
- 複合索引(複数列)は順序が重要。よく絞り込む列を先頭に。等価条件の列 → 範囲条件の列、の順が定石。
- カバリング索引:必要な列がすべて索引に含まれると、本体テーブルを読まずに済み特に速い。
- 付けすぎ注意:索引は書き込み(INSERT/UPDATE/DELETE)を遅くし、容量も食う。使われない索引は害。
索引は「読み取りを速くする代わりに、書き込みを少し遅くする」トレードオフです。だから「効くと確認できた索引だけ」を付けます。実行計画でフルスキャンが索引スキャンに変わったかを必ず確認しましょう。関連する設計は中間テーブルと多対多も参考になります。
③ どうしてもダメなら:非正規化・ビュー・キャッシュ
SQL・プログラム・索引を尽くしても要件に届かないときの最後の手段です。これらは速さと引き換えに複雑さ(データの二重管理・古さ)を抱えるので、順番を守って最後に検討します。
とくに誤解が多いのが「普通のビュー(VIEW)を作れば速くなる」という思い込み。通常のビューはただの保存されたSQLで、実行のたびに中身が走るため速度対策にはなりません(整理・再利用のための仕組み)。速度目的ならマテリアライズドビューやサマリーテーブルです。キャッシュはRedisなどを使いますが、「古いデータを見せない」無効化の設計が伴います。
なぜMySQL・PostgreSQL・Oracleで共通なのか
製品は違っても、リレーショナルDBの中身の仕組みが似ているため、チューニングの考え方は共通します。
| 共通する仕組み | チューニングへの意味 |
|---|---|
| コストベース最適化 | DBが「どの方法が安いか」を見積もって実行計画を決める。だから実行計画を読むスキルがどのDBでも効く。 |
| 統計情報 | 最適化はテーブルの統計(行数・値の分布)に依存。統計が古いと誤った計画になる。更新も対策の一つ。 |
| B-treeインデックス | 索引の基本構造が共通。だから「WHERE/JOIN/ORDER BYの列に付ける」「加工すると効かない」という原則も共通。 |
| 結合・走査の方式 | フルスキャン/索引スキャン、各種JOIN方式という概念が共通。フルスキャンを減らすのが基本方針。 |
つまり、製品固有のコマンドを覚える前に「測って、無駄なSQLを直し、索引を当てる」という土台を身につければ、どのRDBMSでも通用します。より深い設計・最適化はデータベーススペシャリスト試験(SQL設計・性能)の観点も参考になります。
よくある落とし穴
いきなりサーバー増強
SQLが無駄なままハードを強くしても、お金で問題を先送りするだけ。まず測って直すのが安上がりで確実。
索引を闇雲に全列へ
「とりあえず全部に索引」は書き込みを重くし容量も食う。効くと確認できたものだけに絞る。
本番と違う環境で測る
データ量が少ない開発環境では遅さが再現しない。件数や分布が本番に近い状態で計測する。
RDBMSのパフォーマンスチューニングに関するよくある質問
何から手を付ければいいですか?
まず測ることです。実行計画(EXPLAIN)とスロークエリログで「どのクエリが・なぜ遅いか」を特定します。そのうえでSQLと呼び出し側プログラム(N+1・取りすぎ)→ 索引 → 最後にキャッシュの順で、安くて効果の大きいものから直します。
索引を付ければ速くなりますか?
多くの場合、大きく効きます。特にWHERE・JOIN・ORDER BYで使う列に適切な索引があると劇的に速くなります。ただし付けすぎは書き込みを遅くするため、実行計画で効果を確認しながら必要なものだけに絞ります。列を加工する書き方だと索引が効かない点にも注意します。
N+1問題とは何ですか?
一覧を取得したあと、各行ごとにループで追加のクエリを発行してしまい、クエリ数が「1+N回」に膨らむ問題です。ORM使用時に起きやすく、JOINやまとめ取得(IN句)で数回に減らすのが対策です。索引よりも先に疑うべき定番の原因です。
ビュー(VIEW)を作れば速くなりますか?
通常のビューは速度対策にはなりません。ビューは「保存されたSQL」で、参照のたびに中身が実行されるためです。速度目的なら、結果を実体として保存するマテリアライズドビュー(PostgreSQL・Oracle)やサマリーテーブルを使います。
MySQLとPostgreSQL、Oracleでチューニングは違いますか?
コマンドや細部は違いますが、基本の考え方は共通です。いずれもコストベース最適化・統計情報・B-treeインデックスで動くため、「測る → 無駄なSQLを直す → 索引を当てる → 最後にキャッシュ」という順序と原則はそのまま通用します。
まとめ
RDBMSのチューニングは、「安くて効果の大きい順」に手を打つのが鉄則です。まず実行計画とスロークエリログで測り、次にSQLと呼び出し側プログラム(N+1・取りすぎ・索引が効かない書き方)を直し、それからWHERE・JOIN・ORDER BYの列に索引を当て、どうしても足りないときだけ非正規化・マテリアライズドビュー・キャッシュを検討します。MySQL・PostgreSQL・Oracleで共通なのは、コストベース最適化・統計情報・B-treeインデックスという土台が同じだから。製品固有のコマンドより、この順序と考え方を身につけるのが、どのDBでも通用する近道です。
参考リンク
- 関連記事: SQLite・MySQL・PostgreSQLの違い / 中間テーブルと多対多 / 本番DBマイグレーションの注意点
- 関連記事: Redis(キャッシュ)とは / データベーススペシャリスト試験(SQL設計・性能)
- 用語集: ORM / Redis / キャッシュ