スキップしてコンテンツを表示

Amazon RDS for MySQL のスロークエリをトラブルシューティングし、パフォーマンスを改善する方法を教えてください。

所要時間3分
0

Amazon Relational Database Service (Amazon RDS) for MySQL におけるスロークエリをトラブルシューティングし、パフォーマンスを改善したいです。

簡単な説明

Amazon RDS では、次の問題が原因でクエリのパフォーマンスが低下する可能性があります。

  • 不十分なインデックス作成や非効率的なバッファプールの使用など、ワークロードとリソースの使用に関する問題
  • 非効率的なクエリ実行計画
  • リソース競合
  • トランザクションのブロック

これらの問題を解決するには、Amazon CloudWatch メトリクス、Performance Insights、Database Insights、および拡張モニタリングを確認して、パフォーマンスのボトルネックを特定します。次に、ボトルネックの問題を解決し、クエリのパフォーマンスを最適化します。

解決策

重要: 2026 年 6 月 30 日に Performance Insights のサポートは終了します。2026 年 6 月 30 日までに、Database Insights の Advanced モードにアップグレードしてください。アップグレードしない場合、Performance Insights を使用する DB クラスターは、デフォルトで Database Insights の Standard モードを使用します。実行計画とオンデマンド分析は、Database Insights の Advanced モードでのみサポートされます。クラスターがデフォルト設定により Standard モードになった場合、コンソールでこれらの機能を使用できない可能性があります。Advanced モードの有効化については、「Amazon RDS で Database Insights の Advanced モードを有効にする」および「Amazon Aurora で Database Insights の Advanced モードを有効にする」を参照してください。

注: AWS コマンドラインインターフェイス (AWS CLI) コマンドの実行中にエラーが発生した場合は、「AWS CLI で発生したエラーのトラブルシューティング」を参照してください。また、AWS CLI の最新バージョンを使用していることを確認してください。

リソースとデータベースのパフォーマンスを監視する

クエリのパフォーマンスをトラブルシューティングするには、Amazon CloudWatch メトリクスを確認して問題の原因を特定します。クエリによって特定のリソースの使用量が増えたり、DB パフォーマンスが低下したりするタイミングを判断するには、CloudWatch コンソールまたは AWS CLI を使用して次のメトリクスをモニタリングします。

  • DatabaseConnections
  • NetworkReceiveThroughput
  • WriteThroughput
  • ReadThroughput
  • WriteLatency
  • ReadLatency
  • WriteIOPS
  • ReadIOPS
  • FreeStorageSpace
  • BurstBalance

DB のパフォーマンスが低い場合は、RDS DB インスタンスの状態をチェックして、パフォーマンスに影響する可能性のあるアクティブなプロセスやスケジュールされたプロセスがないかどうかを確認します。また、Amazon RDS イベントで DB パフォーマンスに影響する可能性のあるイベントがないか確認してください。

ワークロードとリソース使用率を確認する

クエリのパフォーマンスが遅い場合は、ワークロード内の他のクエリを確認して、それらがクエリのパフォーマンスに影響するかどうかを確認してください。最適化する必要のあるクエリを特定するには、Amazon RDS または Amazon Aurora の Database Insights の Advanced モードを有効にできます。

インスタンスが再起動すると、DB インスタンスはキャッシュされたデータを失い、クエリのパフォーマンスを低下させる可能性があります。このコールドキャッシュの問題を防ぐには、次のパラメータを設定し、再起動後のウォーミングアップバッファプールを高速化します。

  • innodb_buffer_pool_dump_at_shutdown
  • innodb_buffer_pool_load_at_startup
  • innodb_buffer_pool_dump_pct

クエリのパフォーマンスを最適化するには、DB インスタンスが InnoDB バッファプールをどれだけ使用しているかを監視するのがベストプラクティスです。詳細については、MySQL のウェブサイトで「Buffer pool (バッファプール)」を参照してください。InnoDB バッファプールの状態を監視するには、Performance Insights の以下のデータベースカウンターを確認してください

  • 論理読み取りリクエストの数については、Innodb_buffer_pool_read_requests カウンターを確認します。
  • InnoDB がバッファプールから処理できず、ディスクから直接読み取る必要があった論理読み取りの数については、Innodb_buffer_pool_reads を確認します。
  • InnoDB がバッファプールから処理できる読み取りの割合については、Innodb_buffer_pool_hit_ratio を確認します。
  • データページを含む InnoDB バッファプールの割合については、Innodb_buffer_pool_usage を確認します。

パラメータグループで slow_query_log を有効化し、ログを CloudWatch Logs に発行することでも、実行速度が遅いクエリを特定できます。

クエリのパフォーマンスを最適化する

クエリのパフォーマンスを最適化するには、クエリ実行プランのニーズに基づいて次のコマンドを実行します。詳細については、MySQL のウェブサイトで「EXPLAIN output format (EXPLAIN 出力フォーマット)」を参照してください。

EXPLAIN を使用してクエリを最適化する

クエリのパフォーマンスの詳細と、クエリが遅延する理由を確認するには、EXPLAIN コマンドを実行します。詳細については、MySQL のウェブサイトで「Optimizing queries with EXPLAIN (EXPLAIN でクエリを最適化する)」を参照してください。

クエリでインデックスが使用されているかどうかを確認するには、**EXPLAIN ** クエリを実行します。EXPLAIN 出力で、テーブル名、使用中のキー、およびクエリがスキャンした行数を確認します。詳細については、MySQL のウェブサイトで「EXPLAIN Statement (EXPLAIN ステートメント)」を参照してください。出力を確認し、次のアクションを実行します。

  • 使用されるキーが出力に表示されていない場合は、WHERE 句でその列にインデックスを作成します。
  • テーブルに必要なインデックスがある場合は、テーブルの統計情報が最新であることを確認してください。詳細については、MySQL のウェブサイトで「The INFORMATION_SCHEMA STATISTICS table (INFORMATION_SCHEMA STATISTICS テーブル)」を参照してください。

ANALYZE TABLE を使用してクエリの統計情報を更新する

テーブルの統計情報が最新でない場合、クエリのパフォーマンスが低下する可能性があります。クエリの統計情報を更新するには、ANALYZE TABLE コマンドを実行します。詳細については、MySQL のウェブサイトで 「ANALYZE TABLE statement (ANALYZE TABLE ステートメント)」を参照してください。

EXPLAIN ANALYZE を使用して、クエリがどのように時間を割り当てているかを確認する

クエリの実行のどの部分が遅いかを判断するには、EXPLAIN ANALYZE クエリを実行して、MySQL がクエリにどのように時間を割り当てているかを確認します。クエリが完了すると、EXPLAIN ANALYZE クエリは計画とその測定値を出力します。詳細については、MySQL のウェブサイトで「Obtaining information with EXPLAIN ANALYZE (EXPLAIN ANALYZE を使用して情報を取得する)」を参照してください。また、SHOW PROFILE を使用して、処理が遅いクエリをプロファイリングし、セッションが最も時間を費やしているステータスを見つけることもできます。詳細については、MySQL のウェブサイトで「SHOW PROFILE statement (SHOW PROFILE ステートメント)」を参照してください。

SHOW FULL PROCESSLIST と拡張モニタリングを使用して操作を確認する

SHOW FULL PROCESSLIST コマンドを実行すると、データベースサーバーで実行されている操作のリストが表示されます。拡張モニタリングを使用してこのリストを確認することもできます。詳細については、MySQL のウェブサイトで「SHOW PROCESSLIST statement (SHOW PROCESSLIST ステートメント)」を参照してください。

履歴リストの長さを確認する

InnoDB トランザクションシステムは、マルチバージョン同時実行制御 (MVCC) を維持します。ワークロードで複数のオープントランザクションや長時間実行するトランザクションが必要な場合は、データベースの履歴リストが長くなることが予想されます。データベースにおいて、オープントランザクションや長時間実行トランザクションを避けることをおすすめします。詳細については、「InnoDB 履歴リストの長さが大幅に増加しました」を参照してください。

履歴リストの長さのサイズを監視しないと、パフォーマンスが時間の経過に伴い低下します。また、履歴リストの長さが増加すると、リソースの消費量増加、SELECT パフォーマンスの低下や不安定化、およびストレージ消費の増加の原因となる可能性があります。

注: 履歴リストの長さは、長時間実行トランザクション以外の要因でも急増する場合があります。パージスレッドがデータベースの変更に追いつけない場合、履歴リストは長いままの状態になります。極端な場合、データベース障害が発生する可能性もあります。

SHOW ENGINE INNODB STATUS コマンドを実行すると、トランザクション処理、待機イベント、デッドロックに関する情報が表示されます。詳細については、MySQL のウェブサイトで「SHOW ENGINE statement (SHOW ENGINE ステートメント)」を参照してください。SHOW ENGINE INNODB STATUS クエリを実行して、履歴リストの長さを確認します。

SHOW ENGINE INNODB STATUS;

出力例:

\------------ TRANSACTIONS ------------Trx id counter 26368570695  Purge done for
 trx's n:o < 26168770192 undo n:o < 0 state: running but idle History list length 1839

Performance Insights を使用して履歴リストの長さを確認するには、次の手順を実行します。

  1. Amazon RDS コンソールを開きます。
  2. ナビゲーションペインで [Performance Insights] を選択し、メトリクスを確認する対象のデータベースを選択します。
  3. [メトリクス] を選択します。
  4. [メトリクス] ダッシュボードページで [カスタムダッシュボード] を選択します。
  5. [ウィジェットの追加] を選択し、Trx Rseg History Len メトリクスを選択します。
  6. [ウィジェットを追加] を選択します。

注: データ操作言語 (DML) の書き込みによって履歴リストの長さが増加する場合は、データベース管理者に書き込みクエリを終了するよう依頼してください。

ブロックされたクエリを解決する

クエリの実行時間が長引いている場合、別のクエリがそのクエリをブロックしている可能性があります。MySQL 8.0 では、data_lock_waits テーブルのパフォーマンススキーマでロック待機を特定できます。詳細については、MySQL のウェブサイトで「Using InnoDB transaction and locking information (InnoDB トランザクションとロック情報を使用する)」を参照してください。次のクエリを実行して、ブロックしているトランザクションを特定します。

SELECT
  r.trx\_id waiting\_trx\_id,    
  r.trx\_mysql\_thread\_id waiting\_thread,      
  r.trx\_query waiting\_query,    
  b.trx\_id blocking\_trx\_id,    
  b.trx\_mysql\_thread\_id blocking\_thread,    
  b.trx\_query blocking\_query    
FROM       performance\_schema.data\_lock\_waits w    
INNER JOIN information\_schema.innodb\_trx b    
  ON b.trx\_id = w.blocking\_engine\_transaction\_id    
INNER JOIN information\_schema.innodb\_trx r    
  ON r.trx\_id = w.requesting\_engine\_transaction\_id;

関連情報

空き容量が不足している RDS for MySQL または MariaDB インスタンスのトラブルシューティング方法を教えてください

他にアクティブなセッションがないにもかかわらず、Amazon RDS for MySQL DB インスタンスへのクエリがブロックされた理由を知りたいです。

コメントはありません

関連するコンテンツ