MySQL の Performance Schema 入門
Performance Schema は MySQL 5.5 で導入された、サーバー内部の詳細なパフォーマンスデータを収集する仕組みです。SHOW STATUS や SHOW PROCESSLIST より詳細な情報が得られ、パフォーマンス問題の根本原因を突き止めるのに役立ちます。
Performance Schema とは
Performance Schema は、MySQL サーバー内部のイベント(クエリ実行、ファイル I/O、ロック待ちなど)を計測し、専用のデータベース performance_schema に保存します。
USE performance_schema;
SHOW TABLES;100 以上のテーブルがありますが、よく使うものは限られています。
有効化の確認
SHOW VARIABLES LIKE 'performance_schema';デフォルトで ON になっています。OFF の場合は my.cnf で有効化します。
[mysqld]
performance_schema = ON重要なテーブル
用途別に主要なテーブルを紹介します。
events_statements_summary_by_digest - クエリのダイジェストごとの統計
events_waits_summary_global_by_event_name - 何を待っているかの統計
file_summary_by_instance - ファイルごとの I/O 統計
memory_summary_global_by_event_name - メモリ使用状況(MySQL 5.7以降)
遅いクエリを見つける
events_statements_summary_by_digest は、クエリパターンごとの実行統計を提供します。
SELECT
DIGEST_TEXT,
COUNT_STAR AS exec_count,
SUM_TIMER_WAIT / 1000000000000 AS total_time_sec,
AVG_TIMER_WAIT / 1000000000000 AS avg_time_sec,
SUM_ROWS_EXAMINED,
SUM_ROWS_SENT
FROM performance_schema.events_statements_summary_by_digest
ORDER BY SUM_TIMER_WAIT DESC
LIMIT 10;このクエリで、合計実行時間が長いクエリパターンがわかります。時間はピコ秒で記録されているため、10^12 で割って秒に変換しています。
フルスキャンが多いクエリ
テーブルフルスキャンが多いクエリを見つけます。
SELECT
DIGEST_TEXT,
COUNT_STAR,
SUM_NO_INDEX_USED,
SUM_NO_GOOD_INDEX_USED
FROM performance_schema.events_statements_summary_by_digest
WHERE SUM_NO_INDEX_USED > 0
ORDER BY SUM_NO_INDEX_USED DESC
LIMIT 10;SUM_NO_INDEX_USED が大きいクエリは、インデックスが使われていない可能性があります。
待機イベントの分析
何を待っているかがわかると、ボトルネックが特定しやすくなります。
SELECT
EVENT_NAME,
COUNT_STAR,
SUM_TIMER_WAIT / 1000000000000 AS total_wait_sec
FROM performance_schema.events_waits_summary_global_by_event_name
WHERE COUNT_STAR > 0
ORDER BY SUM_TIMER_WAIT DESC
LIMIT 10;| イベント名のパターン | 意味 |
|---|---|
| wait/io/file/* | ファイル I/O 待ち |
| wait/synch/mutex/* | Mutex 待ち |
| wait/synch/rwlock/* | Read-Write ロック待ち |
| wait/lock/table/* | テーブルロック待ち |
ファイル I/O 待ちが多ければディスク性能の問題、Mutex 待ちが多ければ並行処理の競合が疑われます。
ファイル I/O の詳細
どのファイルへの I/O が多いか確認できます。
SELECT
FILE_NAME,
COUNT_READ,
COUNT_WRITE,
SUM_TIMER_READ / 1000000000000 AS read_time_sec,
SUM_TIMER_WRITE / 1000000000000 AS write_time_sec
FROM performance_schema.file_summary_by_instance
ORDER BY SUM_TIMER_READ + SUM_TIMER_WRITE DESC
LIMIT 10;特定のテーブルファイルや redo ログへのアクセスが集中していないか確認できます。
メモリ使用状況(MySQL 5.7以降)
どのコンポーネントがメモリを消費しているか確認できます。
SELECT
EVENT_NAME,
CURRENT_NUMBER_OF_BYTES_USED / 1024 / 1024 AS current_mb
FROM performance_schema.memory_summary_global_by_event_name
ORDER BY CURRENT_NUMBER_OF_BYTES_USED DESC
LIMIT 10;計測対象の設定
デフォルトでは一部のイベントしか計測されません。詳細な分析が必要な場合は、setup テーブルで設定を変更します。
-- 現在の設定を確認
SELECT * FROM performance_schema.setup_instruments WHERE NAME LIKE '%statement%';
-- 特定のイベントを有効化
UPDATE performance_schema.setup_instruments
SET ENABLED = 'YES', TIMED = 'YES'
WHERE NAME LIKE 'wait/io/file/%';ただし、計測対象を増やすとオーバーヘッドも増えます。必要なものだけを有効化しましょう。
統計のリセット
長期間運用していると統計が累積します。特定の期間の分析をしたい場合はリセットします。
-- 全テーブルの統計をリセット
CALL sys.ps_truncate_all_tables(FALSE);
-- 特定のテーブルだけリセット
TRUNCATE TABLE performance_schema.events_statements_summary_by_digest;sys スキーマとの連携
Performance Schema のデータは生のままだと読みにくいため、次回紹介する sys スキーマと組み合わせて使うのが一般的です。sys スキーマは Performance Schema のデータを人間が読みやすい形式でビューとして提供します。
Performance Schema は MySQL の詳細な内部動作を可視化する強力なツールです。最初は複雑に感じますが、よく使うテーブルから始めて徐々に活用範囲を広げていきましょう。