MySQLが遅い時の調査と原因特定|効果的な分析手法と解決策

MySQLのパフォーマンスが低下し、システム全体のレスポンスが遅くなると、ユーザー体験の悪化やビジネス機会の損失につながります。
ただし、MySQLの遅さの原因は、クエリそのもの、テーブル設計やインデックス、サーバー設定、OS・ストレージ・ネットワークなど多岐にわたるため、感覚的に判断するのではなく、まずは事実ベースで切り分けることが重要です。 

本記事では、MySQLが遅いときに最初に行うべき調査方法から、クエリやスキーマの問題点の特定、サーバーやインフラ起因のボトルネック調査まで、原因の調べ方を体系的に解説します。
さらに、根本的な改善の進め方と、株式会社パソナデータ&デザインのサポートサービスについてもご紹介します。

※本記事は主に MySQL 8.0系 を前提に解説しています。MySQL 5.7以前では利用できない機能や、挙動・設定が異なる項目があります。 たとえば EXPLAIN ANALYZE は MySQL 8.0.18 で実装された機能です。

目次

MySQLが遅いときにまず行うべき調査とは?

「最近データベースの動作が遅い気がする」と感じても、原因が分からず手を付けられないケースは少なくありません。

このようなときに重要なのは、ログ、実行中プロセス、実行計画、負荷状況といった観点から現状を可視化し、どこにボトルネックがあるかを段階的に切り分けることです。

スロークエリログと一般ログの確認

MySQLには、実行に時間がかかったSQLを記録する スロークエリログ があります。

スロークエリログを有効にすると、long_query_time を超え、かつ min_examined_row_limit 以上の行を調べたSQL などが記録対象となり、どのクエリに最適化余地があるかを把握しやすくなります。ログには Query_time や Lock_time なども出力されるため、単純に処理時間が長いのか、ロック待ちが影響しているのかを見分ける手がかりになります。

一方、一般ログ(general query log) を有効にすると、サーバーが受け取ったクエリを広く記録できます。

ただし、一般ログは出力量が多く、性能影響やログ肥大化の懸念もあるため、調査目的で短時間だけ有効化する 運用が一般的です。

なお、スロークエリログはクエリの実行完了後に書き込まれるため、今まさに発生している詰まりをリアルタイムで見る用途には向きません。リアルタイムの確認は、後述する SHOW FULL PROCESSLIST などと併用するのが有効です。

実行中クエリの確認と再現テスト

リアルタイムで遅延が発生している場合は、SHOW FULL PROCESSLIST や Performance Schema の processlist 情報を使って、現在どの処理が実行中なのかを確認します。

これにより、実行時間が長いクエリ、ロック待ちが発生しているスレッド、特定ユーザーやアプリケーションからの偏ったアクセスなどを把握できます。SHOW PROCESSLIST でも確認できますが、FULL を付けないとSQL文が途中で切れるため、実務上は SHOW FULL PROCESSLIST を使うほうが安全です。

問題になっているSQLが見つかったら、可能であれば開発環境やステージング環境で再現テストを行います。

その際は、本番に近いデータ量、インデックス構成、統計情報、同時実行条件 を意識することが大切です。本番と大きく異なる条件では、遅延の原因を正しく再現できないことがあります。

EXPLAINとEXPLAIN ANALYZEで実行計画を取得する

クエリが遅い原因を深掘りするには、実行計画の確認 が欠かせません。

EXPLAIN を使うと、MySQLがどの順序でテーブルを参照し、どのインデックスを利用し、どの程度の行数を読み込む見込みなのかを確認できます。特に type、key、rows などの情報は、フルスキャンや不適切な結合順序、インデックス未使用の兆候を見つけるうえで有用です。

さらに、MySQL 8.0.18以降では EXPLAIN ANALYZE が利用可能です。

これは実際にクエリを実行しながら、各処理段階の実測時間や行数を確認できる機能で、見積りベースの EXPLAIN よりも実態に近い分析ができます。見積り行数と実測行数に大きな乖離がある場合は、統計情報やデータ分布、SQLの書き方に問題がある可能性があります。

ベンチマークと負荷テストによる問題の再現

本番環境での遅延が、特定の時間帯やアクセス集中時のみ発生する場合は、ベンチマークや負荷テストで条件を再現することが有効です。

たとえば、MySQLに付属する mysqlslap や、広く利用されている外部ベンチマークツール sysbench などを使うことで、同時接続数やクエリ実行回数を増やしたときの応答時間やスループットの変化を確認できます。

負荷テストでは、単に「遅くなるかどうか」だけでなく、どの負荷水準から急激に性能が悪化するのか、CPU・メモリ・I/O・ロック待ちのどれが先に限界に達するのか を見ることが重要です。

また、改善前後で同じ条件のテストを行えば、チューニングの効果を数値で比較できます。

MySQLのクエリとスキーマのどこが遅いのか原因特定する

MySQLのパフォーマンスが低下する背景には、原因が分からず対処に悩んでいるケースも少なくありません。多くの場合、その要因はクエリやスキーマ設計に潜んでいます。ここでは、よくある非効率なパターンと、それらを見つけるための具体的な視点を解説します。

非効率なクエリの典型例と改善ポイント

非効率なクエリには、いくつかの典型的なパターンがあります。たとえば、SELECT * を使ってすべてのカラムを取得するクエリは、必要なデータ量が増えるため遅くなりがちです。必要なカラムだけを明示的に指定することで、データ転送量と処理時間を削減できます。

また、WHERE句で関数を使った条件指定も要注意です。たとえば、WHERE YEAR(created_at) = 2024 のように列に関数を適用する条件は、通常のインデックスを活かしにくく、フルスキャンや広い範囲の走査になりやすいため注意が必要です。多くの場合は、created_at >= ‘2024-01-01’ AND created_at < ‘2025-01-01’ のような範囲条件に書き換えるほうが有利です。

この場合は、WHERE created_at >= ‘2024-01-01’ AND created_at < ‘2025-01-01’ のように書き換えることで、インデックスが有効になります。

※DATETIME型の場合、BETWEEN ‘2024-12-31’ だと時刻分が漏れる可能性があるため、範囲は「以上・未満」で書くと安全です。

サブクエリの多用も、パフォーマンスを低下させる原因です。特にサブクエリが相関サブクエリとして使われている場合、外側のクエリの行ごとに内側のクエリが実行されるため、処理時間が大幅に増えます。可能であれば、JOINやEXISTSに書き換えることで改善できるケースがあります。

実行計画(EXPLAIN)で読み解く「遅い原因」の見つけ方

EXPLAINで出力される実行計画には、いくつかの重要な項目があります。まず注目すべきは「type」カラムです。この値が「ALL」や「index」の場合、全行スキャンやインデックスの全走査が行われているため、遅くなる可能性が高いです。

理想的なのは「ref」や「eq_ref」といった値で、これらはインデックスを介した効率的なアクセスを意味します。また、「rows」カラムを見ることで、クエリが何行のデータを調べるのかが分かります。この値が大きい場合は、絞り込み条件やインデックスの見直しが必要です。

さらに、「Extra」カラムには追加情報が表示されます。「Using filesort」や「Using temporary」といったExtra に Using filesort や Using temporary が表示される場合、追加のソート処理や一時テーブル利用が発生していることを示します。必ずしも問題とは限りませんが、データ量が多い場合は性能劣化につながることがあるため、確認ポイントになります。

これらの情報を総合的に判断することで、どこに問題があるのかを特定できます。

インデックス最適化の基本

インデックスは、データベースの検索速度を向上させる重要な要素ですが、適切に設計されていないと効果が得られません。まず、WHERE句やJOIN句で頻繁に使われるカラムには、インデックスを作成しておくことが基本です。

複数のカラムを組み合わせて検索する場合は、複合インデックスが有効です。ただし、カラムの順序が重要で、複合インデックスでは列の順序が重要です。MySQLでは左端プレフィックスに合致する条件で使われやすいため、先頭列は単純にカーディナリティだけで決めるのではなく、実際の WHERE 条件、JOIN 条件、ORDER BY でどのように使うかを基準に設計することが重要です。

また、インデックスは更新時のオーバーヘッドも発生するため、必要以上に作成するとINSERTやUPDATEが遅くなります。

定期的にインデックスを見直し、不要なものを減らすことも大切です。なお、SHOW INDEX で分かるのは インデックスの定義(どんな索引があるか)であり、実際にどれだけ使われているか(使用状況)までは分かりません。

使用傾向を把握したい場合は、Performance Schema の集計情報や、スロークエリログ/実行計画(EXPLAIN)を併用し、「実際のクエリで使われている索引か」「改善インパクトが大きい索引か」を優先して判断しましょう。

スキーマ設計・データ型が遅さに与える影響

スキーマ設計の良し悪しも、パフォーマンスに直結します。たとえば、データ型の選択を誤ると、無駄なストレージ容量やメモリを消費し、処理速度が低下します。整数を格納するのにVARCHARを使ったり、固定長データにTEXTを使ったりするのは非効率的です。

また、正規化しすぎるとJOINが多くなり、クエリが複雑化します。逆に正規化が不足すると、データの冗長性が生まれ、更新時の整合性管理が難しくなります。アクセスパターンに応じて、適度な非正規化を検討することも有効です。

文字セットや照合順序(collation)の選択も重要です。MySQL 8.0では基本的に utf8mb4 の利用を推奨します。古い環境で使われがちな utf8 は実質的に 3バイトUTF-8(utf8mb3)の扱いとなり、将来的な互換性の観点でも推奨されません。

文字列カラムはサイズ増加の影響を受けやすいため、必要十分な桁数・型(VARCHAR/TEXT等)を適切に選び、インデックス設計もあわせて最適化するのが現実的な改善につながります。

MySQLサーバー・インフラ要因のボトルネック調査

ここまでご紹介してきたクエリやスキーマに問題がなくても、サーバーやインフラの設定が適切でないとパフォーマンスは発揮できません。ここでは、インフラ観点での調査ポイントを見ていきます。

メモリ・バッファ設定の最適化チェック

MySQLは、メモリを効率的に使うことで高速な処理を実現しています。特に重要なのが、InnoDBバッファプール(innodb_buffer_pool_size)の設定です。これは、データやインデックスをメモリ上にキャッシュする領域で、大きく設定するほど高速化が期待できます。

専用のMySQLサーバーでは、innodb_buffer_pool_size に物理メモリの最大80%程度を割り当てることが多いですが、これはあくまで目安です。OSや他プロセス、接続数、ワークロードも考慮し、スワップが発生しない範囲で調整することが重要です。

ただし、他のプロセスも動作している場合は、メモリ不足によるスワップが発生しないよう注意が必要です。

また、一時テーブル(テンポラリ)のメモリ設定や、ソート/結合で利用されるメモリ関連パラメータも確認しましょう。設定が小さすぎると、処理がメモリ内で完結せずディスクI/Oが増え、レスポンスが悪化することがあります。

SHOW VARIABLES で現在値を確認しつつ、テスト環境で負荷をかけて効果と副作用(メモリ逼迫)を確認しながら調整するのが安全です。

※なお、MySQL 8.0ではクエリキャッシュ(Query Cache)は廃止されています(5.7以前のみの概念です)。

ディスクI/Oとストレージ性能の調査ポイント

データベースの処理速度は、ディスクI/Oの性能に大きく依存します。メモリに乗り切らないデータにアクセスする場合、ディスクからの読み書きが発生するため、ストレージの速度が重要になります。

HDD(ハードディスク)よりもSSD(ソリッドステートドライブ)の方が、ランダムアクセス性能が圧倒的に優れています。特にデータベースはランダムアクセスが多いため、SSDの導入は大きな効果があります。さらに、NVMe SSDを使えば、SATA SSDよりもさらに高速な処理が可能です。

また、iostatやvmstatといったコマンドを使うと、ディスクのI/O状況を確認できます。iostat や vmstat でI/O待ち時間や使用率が高い状態が続いている場合、ストレージがボトルネックになっている可能性があります。CPU、メモリ、クエリ内容もあわせて確認しながら判断しましょう。

CPU負荷・スレッド・ロックのボトルネック確認

CPUの使用率が常に高い場合は、処理が集中しすぎている、または非効率なクエリが大量に実行されている可能性があります。topやhtopコマンドでCPU使用率を確認し、MySQLプロセスがどの程度リソースを消費しているかを把握しましょう。

また、同時実行や接続数に関する設定も重要です。max_connections同時接続数の上限であり、上限を超えると新規接続が失敗してアプリ側のエラーにつながります。一方で高くしすぎると、接続ごとのメモリ消費が積み上がり、全体の不安定化を招くことがあります。

innodb_thread_concurrencyInnoDB内部で同時に実行できるスレッド数を制御する設定ですが、MySQL 8.0では基本的に デフォルト(0=制限なし)のまま運用されることが多く、変更する場合は十分な検証が前提です。まずは遅いクエリやロック、CPU/I/Oの状況を把握し、必要に応じて段階的に調整しましょう。

ロック待ちもパフォーマンス低下の原因です。SHOW ENGINE INNODB STATUSコマンドで、ロックの状況やデッドロックの発生を確認できます。トランザクションの実行時間が長い場合は、ロックの影響範囲を最小化する設計が求められます。

ネットワーク遅延と接続数の調査

データベースサーバーとアプリケーションサーバーが物理的に離れている場合、ネットワーク遅延がレスポンス時間に影響を与えます。ping や mtr は、経路や基本的な遅延傾向、パケットロスの有無を確認する手段として有効です。ただし、アプリケーションから見た実際のDB応答時間とは一致しない場合もあるため、アプリ側・DB側の計測とあわせて評価することが重要です。

また、接続数の管理も重要です。MySQLは、接続ごとにメモリを消費するため、不要な接続が残っているとリソースを圧迫します。SHOW PROCESSLIST で接続状況を確認し、Sleepステータスのまま長時間残っている接続があれば、接続プールの設定やアプリケーション側の接続管理を見直す必要があります。

接続数の上限(max_connections)も適切に設定しましょう。上限を超えると新しい接続が拒否されるため、アプリケーションエラーが発生します。一方、上限を高く設定しすぎると、メモリ不足やパフォーマンス低下を招くことがあります。

監視ツールとログ解析で全体像を可視化する

パフォーマンスの問題を継続的に把握するには、監視ツールの導入が効果的です。Prometheus、Grafana、Zabbix、Datadog、New Relicなどのツールを使うと、リアルタイムでメトリクスを収集し、グラフで可視化できます。

これらのツールでは、クエリの実行時間、スロークエリの発生頻度、CPU・メモリ・ディスクの使用率などを一元的に監視できます。アラート機能を設定しておけば、異常が発生した際に即座に通知を受け取ることも可能です。

また、ログ解析ツール(pt-query-digestなど)を使うと、スロークエリログを集計し、どのクエリが最も時間を消費しているかをランキング形式で確認できます。これにより、優先的に改善すべきクエリを特定しやすくなります。

調査結果から改善までの推奨アクション

調査で得られた情報をもとに、具体的な改善アクションに移る際は、影響範囲と効果のバランスを考慮することが重要です。たとえば、インデックス追加は比較的効果が出やすい改善策ですが、更新系処理の負荷増加やストレージ消費の増加といった副作用もあるため、対象クエリと更新頻度を踏まえて判断することが重要です。

一方、スキーマ変更やサーバー設定の大幅な変更は、影響範囲が広いため慎重な検証が必要です。改善策を実施する前に、必ずテスト環境で効果を確認し、本番環境へは段階的に適用しましょう。

また、改善後も継続的にモニタリングを行い、効果を数値で確認することが大切です。改善が不十分であれば、次の施策を検討します。このサイクルを回すことで、安定したパフォーマンスを維持できます。

MySQLが遅い原因を根本解決するパフォーマンス改善アプローチ

MySQLの遅さの原因が分かっても、「どこから手を付ければいいのか」で迷う方は多いはずです。ここでは、調査結果をもとに優先度を見極めながら、根本的なパフォーマンス改善につなげる実践的なアプローチを整理します。

優先順位のつけ方(クエリ・設定・インフラ)

パフォーマンス改善には複数のアプローチがありますが、すべてを同時に実施するのは現実的ではありません。まず、クエリの最適化から着手することをお勧めします。クエリの改善は、コストが低く効果が大きいケースが多いためです。

次に、設定の見直しは、比較的短時間で着手できる改善策です。メモリやバッファ、接続関連の設定によって効果が出ることもありますが、副作用を避けるため、テスト環境や段階的な適用で検証しながら進めることが重要です。

最後に、インフラの増強(サーバースペックのアップグレード、ストレージの変更など)を検討します。これらは費用や作業負荷が大きいため、他の手段で解決できない場合の選択肢です。

また、影響範囲の大きさも考慮しましょう。たとえば、全体に影響する設定変更よりも、特定のクエリだけを改善する方が安全です。リスクと効果のバランスを見ながら、優先順位を決定することが成功の鍵となります。

改善効果を最大化するチューニング手順

チューニングを行う際は、一度に複数の変更を加えると、どの変更が効果をもたらしたのか分からなくなります。そのため、一つの変更ごとに効果を測定し、結果を記録することが重要です。

まず、ベースラインとなる現状のパフォーマンスを記録します。次に、改善策を一つ実施し、再度ベンチマークを取得します。効果があれば次の施策に進み、効果がなければ元に戻すか別の方法を試します。

また、改善策を本番環境に適用する前に、必ずテスト環境で十分に検証しましょう。予期しない副作用が発生する可能性もあるため、段階的なロールアウトが安全です。たとえば、最初は一部のサーバーだけに適用し、問題がなければ全体に展開するといった方法が有効です。

再発防止のための運用ルール・監視体制

一度改善しても、時間が経つにつれてデータ量が増えたり、新しいクエリが追加されたりすることで、再びパフォーマンスが低下することがあります。そのため、継続的な監視と定期的なレビューが欠かせません。

スロークエリログを定期的に確認し、新たに遅いクエリが発生していないかをチェックしましょう。また、データベースのメトリクスを監視ツールでリアルタイムに追跡し、異常が発生した際には即座に対応できる体制を整えます。

さらに、開発チームと運用チームが連携し、新しい機能をリリースする際にはパフォーマンステストを実施するルールを設けることも重要です。これにより、問題が本番環境に到達する前に発見できます。

株式会社パソナデータ&デザインのMySQLコンサルティングサービス

ここまで、MySQLが遅いときの調査方法や、クエリ・スキーマ・サーバー設定・インフラ観点での原因特定ポイントをご紹介してきました。
ただ実際の現場では、原因が1つだけとは限らず、SQLの見直し、インデックス設計、MySQL内部設定、OSリソース、クラウド環境の構成が複合的に影響していることも少なくありません。

そのため、
「遅い原因は何となく見えてきたが、どこから手を付けるべきか分からない」
「改善案はいくつかあるが、本番影響を考えると判断が難しい」
と感じる場合は、調査から改善までを一貫して支援できる専門サービスの活用も有効です。

株式会社パソナデータ&デザインでは、MySQLパフォーマンス改善をはじめ、高可用性環境の構築や MySQL 8.x へのアップグレード支援 まで対応する MySQL コンサルティングサービスを提供しています。AWS、Azure、GCP 環境にも対応しており、MySQLに関する幅広い課題を支援しています。

記事で解説したような観点を、実環境に即して総合的に調査

パソナデータ&デザインのMySQLコンサルティングでは、単に「遅いSQLを1本直す」だけではなく、
OSのリソース状態、MySQL内部ステータス、スロークエリログ、エラーログ などをもとに、ボトルネックを総合的に分析します。
そのうえで、データベース診断・分析 → ボトルネック特定 → 問題点・改善施策レポート → MySQLチューニング実施 という流れで、改善方針を整理し、実行まで支援します。

たとえば、次のようなケースは相談しやすいテーマです。

  • スロークエリが出ているが、SQLだけの問題か設定やI/Oも絡んでいるか判断できない
  • インデックスを追加すべきか、クエリを書き換えるべきか迷っている
  • サーバースペック増強の前に、チューニングで改善余地があるか知りたい
  • MySQL 5.x / 8.0系から 8.x への移行やアップグレードも視野に入れて検討したい
  • 安定稼働のために高可用性構成も含めて見直したい

原因調査だけで終わらず、改善実行まで相談できる

パフォーマンス改善で難しいのは、原因特定そのものより、
「何を、どの順番で、どこまで直すか」 を決めることです。

パソナデータ&デザインでは、分析結果をもとに改善施策をレポート化し、その後のチューニング実施まで対応しています。
LPでも、テーブル/インデックス定義の最適化、SQLチューニング、パラメータチューニングのアドバイス が明記されており、診断だけで終わらず、改善アクションにつなげやすいのが特長です。

また、MySQL関連では 20年以上の支援実績、DB関連製品提供実績1,000社以上、DB支援プロジェクト1,800社以上、MySQL資格保有者による対応 が打ち出されており、MySQLに特化した知見をもとに相談できる体制が整っています。

こんな場合は、早めの相談がおすすめ

次のような状況であれば、記事の内容を踏まえつつ、実環境の診断を依頼する価値があります。

  • 原因切り分けに時間がかかっており、障害や機会損失のリスクが高まっている
  • 社内にMySQLの性能改善を専門で見られる人がいない
  • その場しのぎの対処ではなく、恒久対策まで整理したい
  • パフォーマンス改善とあわせて、構成見直しやアップグレードも検討したい

MySQLの遅さは、表面的には同じ「レスポンス低下」に見えても、実際には
クエリ、インデックス、設定、OS、ストレージ、クラウド構成 のどこに本質的な原因があるかで、取るべき対応が大きく変わります。
だからこそ、調査結果をもとに優先順位を整理し、改善まで伴走できる支援体制が重要です。

MySQLのパフォーマンス改善やボトルネック調査、アップグレード、高可用性構成の見直しをご検討中の方は、MySQLコンサルティングサービス をご覧ください。

MySQLのコンサルティングサービスはこちら

まとめ

MySQLのパフォーマンス問題は、クエリ、スキーマ、サーバー設定、インフラなど、複数の要因が絡み合って発生します。
本記事では、効果的な調査手法から原因の特定、そして根本的な改善アプローチまでを体系的に解説しました。

  • スロークエリログや実行計画、必要に応じて SHOW FULL PROCESSLIST なども活用し、まずは客観的に問題を把握することが重要です。
  • クエリやスキーマの非効率なパターンを見つけ、実行計画やアクセスパターンを踏まえて、適切なインデックスやデータ型を検討しましょう。
  • サーバーのメモリ、ディスク、CPU、ネットワークなどインフラ全体も確認し、どこが本当のボトルネックかを切り分けることが重要です。InnoDBバッファプールは特に重要な確認ポイントです。
  • 改善は優先順位をつけて段階的に実施し、変更ごとに効果を測定しながら進めることが、確実なチューニングにつながります。
  • 継続的な監視と運用ルールの整備により、パフォーマンス低下の再発を防ぎやすくなります。スロークエリログの定期確認も有効です。

MySQLのパフォーマンスに課題を感じている場合は、まず本記事で紹介した調査手法から着手してみてください。
また、原因の切り分けや改善優先順位の判断が難しい場合は、専門家の支援を活用することで、より効率的かつ安全に改善を進めやすくなります。

 

よかったらシェアしてね!
  • URLをコピーしました!
目次