performance_schemaをsysで使い倒す!
パフォーマンススキーマとは
「パフォーマンススキーマ」は、MySQL 5.5.3から導入されたパフォーマンスモニタリングのためのストレージエンジンです(第6回でも一部利用)。MySQL 5.5時代はローレベルな情報(mutex待ち、ロック待ち、I/O待ち)のみを提供し、通常運用に役に立つ情報はありませんでしたが、MySQL 5.6以降で大きく機能が追加され、十分クエリーチューニングに役立つ強力なツールに生まれ変わりました。
MySQL 5.6以降ではデフォルトでONに設定されるようになったパフォーマンススキーマですが、MySQL 5.5時代をご存知の方は明示的にOFFにしているかも知れません(MySQL 5.5のパフォーマンススキーマはパフォーマンスへのオーバーヘッドが非常に大きかった上に、大量にメモリーを利用した)。最近のパフォーマンススキーマはON/OFFに再起動が必要な点こそ変わりませんが、パフォーマンスオーバーヘッド、メモリー使用量ともに大幅に改善されています。また、取得できる情報も「ステートメント(ダイジェスト)単位での各種待ち状態の統計」、「各ステージでの経過時間」、「トランザクション単位での統計」などが追加され、さらに「スキーマ単位、テーブル単位で記録するか否か」、「ユーザー単位、ホスト単位で記録するか否か」を設定できるようになっています。
このような大幅な機能追加とオーバーヘッドの削減により、MySQL 5.6以降ではONにする価値は十分あるのではないでしょうか(筆者の会社の本番環境では、MySQL 5.6以降のパフォーマンススキーマは原則ONにしている)。
パフォーマンススキーマの設定
ややこしい話ですが、パフォーマンススキーマの機能はデータの格納/取り出しにPERFORMANCE_SCHEMA
ストレージエンジンを利用し、名前空間としてperformance_schema
データベース(SHOW DATABASES
を実行すると performance_schema
が表示される)を利用します。また、パフォーマンススキーマを有効化するオプションはperformance_schema
です。なお、これらのパフォーマンススキーマ(機能)、performance_schema
データベース、performance_schema
オプションはp_s
と略されることが多いです(一般ユーザー同士でPERFORMANCE_SCHEMA
ストレージエンジンに言及する機会は少ない。PERFORMANCE_SCHEMA
ストレージエンジンを省略する場合は perfschema
が使われることが多い)。
以下で説明するコマンドの出力例などは全てMySQL 5.7.13のものです。原則、同様の手順でMySQL 5.6でも設定できますが、MySQL 5.7で新規に追加された機能があるため、一部MySQL 5.6では確認できないテーブルや行、カラムが存在します。気が付いたら「MySQL 5.7で追加されたんだな」と思ってください。
パフォーマンススキーマが有効かどうかは、performance_schema
変数を参照することで確認できます。
mysql> SHOW VARIABLES LIKE 'performance_schema';
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| performance_schema | ON |
+--------------------+-------+
1 row in set (0.01 sec)
パフォーマンススキーマの設定に関するテーブルは、performance_schema
データベースでsetup_
の接頭辞を持つテーブルにまとめられています。
mysql> SHOW TABLES FROM performance_schema LIKE 'setup\_%';
+-----------------------------------------+
| Tables_in_performance_schema (setup\_%) |
+-----------------------------------------+
| setup_actors |
| setup_consumers |
| setup_instruments |
| setup_objects |
| setup_timers |
+-----------------------------------------+
5 rows in set (0.00 sec)
パフォーマンススキーマはSQLで設定します(起動時のみオプションでも設定可能。パフォーマンススキーマ起動構成を参照)。現在の設定を確認するにはSELECT
ステートメントを、設定を変更するにはUPDATE .. SET .. WHERE ..
ステートメントを使用します。
setup_actors
パフォーマンススキーマによる統計の記録をユーザー単位、接続元ホスト単位で有効にするための設定ができます。デフォルトではHOST = '%', USER = '%', ENABLED = 'YES', HISTORY = 'YES'
の行が設定されており、全ての接続元からの全てのユーザーが統計の取得対象になっています。この1行を削除し、HOST = '192.168.0.101', USER = '%', ENABLED = 'YES', HISTORY = 'YES'
の行を追加すると、特定のホストからの接続のみを記録し、その他のホストからの接続はオーバーヘッドを削減する、といった使い方ができます(このテーブルの情報はMySQLを再起動すると消える(=デフォルトのHOST = '%', USER = '%', ENABLED = 'YES', HISTORY = 'YES'
に戻る)。必要ならばinit_file
オプションでこのテーブルの設定をスタートアップ時に編集するようにしておくと良い)。
setup_actors
テーブルへの設定は、次回のコネクション確立時から有効になります。コネクションプールを利用している環境では注意してください(現在接続中のスレッド単位でパフォーマンススキーマの機能を有効/無効にするにはperformace_schema.threads
テーブルを利用する)。
setup_consumers
setup_consumers
テーブルでは、パフォーマンススキーマが計測した統計を記録するかどうかを設定します。
mysql> SELECT * FROM setup_consumers;
+----------------------------------+---------+
| NAME | ENABLED |
+----------------------------------+---------+
| events_stages_current | NO |
| events_stages_history | NO |
| events_stages_history_long | NO |
| events_statements_current | YES |
| events_statements_history | YES |
| events_statements_history_long | NO |
| events_transactions_current | NO |
| events_transactions_history | NO |
| events_transactions_history_long | NO |
| events_waits_current | NO |
| events_waits_history | NO |
| events_waits_history_long | NO |
| global_instrumentation | YES |
| thread_instrumentation | YES |
| statements_digest | YES |
+----------------------------------+---------+
15 rows in set (0.00 sec)
MySQL 5.7.13現在、デフォルトは上記のようになっています。コンシューマーの名前(setup_consumers.name
の値)とperformance_schema
スキーマ内のテーブル名は大よそ紐づいているので、なんとなく何が有効/無効なのか(また、どこを有効にすると取得したい情報が取れるのか)がわかるかと思います。詳細はリファレンスマニュアルに記載があります。events_stages_*
はプロファイラーとしての機能を(前回も利用)、events_statements_*
はステートメント単位の統計情報を記録するための機能を、events_waits_*
は非常にローレベルなmutexの競合やファイルシステムのsyncなど、MySQLが「待って」いた統計情報を記録するための機能を提供します。
これらがENABLED = NO
になっていた場合、performance_schema
データベース上にテーブルは残りますが、中身は記録されません(起動後にUPDATE
ステートメントでENABLED = NO
にした場合、それ以降の統計情報が記録されなくなる)。
setup_instruments
setup_instruments
テーブルには、setup_consumers
テーブルよりさらに細分化された「パフォーマンススキーマがどのイベントの統計情報を記録するか」が設定されています。name
カラムの値はスラッシュで区切られた名前空間を持ちます。ざっくりとSQLでENABLED = YES
になっている項目とENABLED = NO
になっている項目の数を数えてみます。
mysql> SELECT SUBSTRING_INDEX(`name`, '/', 2) AS short_name, ANY_VALUE(name) AS example, SUM(ENABLED = 'YES') AS enabled, SUM(ENABLED = 'NO') AS disabled FROM setup_instruments GROUP BY short_name;
+---------------------------+-----------------------------------------------------+---------+----------+
| short_name | example | enabled | disabled |
+---------------------------+-----------------------------------------------------+---------+----------+
| idle | idle | 1 | 0 |
| memory/archive | memory/archive/FRM | 0 | 2 |
| memory/blackhole | memory/blackhole/blackhole_share | 0 | 1 |
| memory/client | memory/client/mysql_options | 0 | 7 |
| memory/csv | memory/csv/TINA_SHARE | 0 | 5 |
| memory/federated | memory/federated/FEDERATED_SHARE | 0 | 1 |
| memory/innodb | memory/innodb/adaptive hash index | 0 | 85 |
| memory/keyring | memory/keyring/KEYRING | 0 | 1 |
| memory/memory | memory/memory/HP_SHARE | 0 | 4 |
| memory/myisam | memory/myisam/MYISAM_SHARE | 0 | 21 |
| memory/myisammrg | memory/myisammrg/MYRG_INFO | 0 | 2 |
| memory/mysys | memory/mysys/max_alloca | 0 | 21 |
| memory/partition | memory/partition/ha_partition::file | 0 | 3 |
| memory/performance_schema | memory/performance_schema/mutex_instances | 70 | 0 |
| memory/sql | memory/sql/Locked_tables_list::m_locked_tables_root | 0 | 152 |
| memory/vio | memory/vio/ssl_fd | 0 | 3 |
| stage/innodb | stage/innodb/alter table (end) | 8 | 0 |
| stage/mysys | stage/mysys/Waiting for table level lock | 0 | 1 |
| stage/sql | stage/sql/After create | 1 | 119 |
| statement/abstract | statement/abstract/Query | 3 | 0 |
| statement/com | statement/com/Sleep | 32 | 0 |
| statement/scheduler | statement/scheduler/event | 1 | 0 |
| statement/sp | statement/sp/stmt | 16 | 0 |
| statement/sql | statement/sql/select | 141 | 0 |
| transaction | transaction | 0 | 1 |
| wait/io | wait/io/file/sql/map | 55 | 3 |
| wait/lock | wait/lock/table/sql/handler | 1 | 1 |
| wait/synch | wait/synch/mutex/sql/TC_LOG_MMAP::LOCK_tc | 0 | 257 |
+---------------------------+-----------------------------------------------------+---------+----------+
28 rows in set (0.01 sec)
例えば、25行目(下から3行目)を見るとname LIKE 'wait/io%'
に属する項目は58あり、そのうちENABLED = YES
は55項目、ENABLED = NO
は3項目、そしてname LIKE 'wait/io%'
に属する項目の1つの例としてwait/io/file/sql/map
があるようだ、といったことを上記のSQLから見て取れます。
setup_instruments
テーブルの設定とsetup_consumers
テーブルの設定のうち、両方がENABLED = YES
になっているものがパフォーマンススキーマで計測、蓄積されます(前回の記事を参照。setup_consumers
テーブルのevents_stages_*
とsetup_instruments
テーブルのstage/sql/*
を両方有効にしている)。改めての注意になりますが、performance_schema
データベースで行った設定変更は、原則「即時」にサーバー「全体」へ反映されます。WHERE
句なしでENABLED = YES
にするのはステージング環境だけに留めておきましょう(設定項目によってはまだオーバーヘッドがある)。
setup_objects
setup_objects
テーブルは、オブジェクト単位でパフォーマンススキーマの有効/無効を設定できます。
mysql> SELECT * FROM setup_objects;
+-------------+--------------------+-------------+---------+-------+
| OBJECT_TYPE | OBJECT_SCHEMA | OBJECT_NAME | ENABLED | TIMED |
+-------------+--------------------+-------------+---------+-------+
| EVENT | mysql | % | NO | NO |
| EVENT | performance_schema | % | NO | NO |
| EVENT | information_schema | % | NO | NO |
| EVENT | % | % | YES | YES |
| FUNCTION | mysql | % | NO | NO |
| FUNCTION | performance_schema | % | NO | NO |
| FUNCTION | information_schema | % | NO | NO |
| FUNCTION | % | % | YES | YES |
| PROCEDURE | mysql | % | NO | NO |
| PROCEDURE | performance_schema | % | NO | NO |
| PROCEDURE | information_schema | % | NO | NO |
| PROCEDURE | % | % | YES | YES |
| TABLE | mysql | % | NO | NO |
| TABLE | performance_schema | % | NO | NO |
| TABLE | information_schema | % | NO | NO |
| TABLE | % | % | YES | YES |
| TRIGGER | mysql | % | NO | NO |
| TRIGGER | performance_schema | % | NO | NO |
| TRIGGER | information_schema | % | NO | NO |
| TRIGGER | % | % | YES | YES |
+-------------+--------------------+-------------+---------+-------+
20 rows in set (0.01 sec)
デフォルトで入っているmysql
データベース(権限などシステム管理用のデータベース)、information_schema
データベース(MySQLの内部情報をSQLで参照するための疑似データベース)、performance_schema
データベースは、他のテーブルの設定に関わらずENABLED = NO
が設定されています。パフォーマンススキーマの統計情報は全ての条件をクリアした場合のみ(どれか1つの設定でもENABLED =
NO
になっている場合は取得されない)記録されるため、特定のテーブルのみ参照し、その他にもオーバーヘッドを抑えたい場合などにはこのテーブルが有効かも知れません。
パフォーマンススキーマの参照
パフォーマンススキーマから統計情報を引き出すには、performance_schema
データベースのsetup_*
以外のテーブルにアクセスします。テーブルの名前と、そのテーブルにアクセスして確認できる統計情報は概ね一致しているので、まずはテーブルの名前で興味をそそられるものを探して開いてみるのが良いでしょう。
mysql> SELECT * FROM file_instances;
+----------------------------------------------------------------------------------------------------+---------------------------------------------+------------+
| FILE_NAME | EVENT_NAME | OPEN_COUNT |
+----------------------------------------------------------------------------------------------------+---------------------------------------------+------------+
| /usr/mysql/5.7.13/share/english/errmsg.sys | wait/io/file/sql/ERRMSG | 0 |
| /usr/mysql/5.7.13/share/charsets/Index.xml | wait/io/file/mysys/charset | 0 |
| /usr/mysql/5.7.13/keyring/keyring | wait/io/file/keyring_file/keyring_file_data | 0 |
| /usr/mysql/5.7.13/data/ibdata1 | wait/io/file/innodb/innodb_data_file | 3 |
..
| /usr/mysql/5.7.13/data/p_s/file_instances.frm | wait/io/file/sql/FRM | 0 |
+----------------------------------------------------------------------------------------------------+---------------------------------------------+------------+
188 rows in set (0.00 sec)
これらのテーブルは概して横に長い(カラム数が多く、格納されている文字列も長い)ことが多いため、MySQL WorkbenchなどのGUIツールを使うか、mysql
コマンドラインクライアントのpager less -S
サブコマンドなどで見ることをお勧めします。
setup_*
テーブルと違い、これらのテーブルはTRUNCATE
することで「今まで蓄積した統計情報をリセット」できます。パフォーマンススキーマの統計は累積値なので、何らかのチューニングを実施してその効果を測りたい場合は一度統計をリセットすると良いでしょう(リセット前の情報も保管しておきたい場合はSQLでアクセスして任意のスキーマにINSERT .. SELECT
ステートメントでテーブル情報をコピーすれば良い)。なお、PERFORMANCE_SCHEMA
ストレージエンジンはメモリー上にデータを蓄積するため、MySQLを再起動した場合はそれまでの統計情報はリセットされます。
パフォーマンススキーマが集めた統計情報の他に、ストレージエンジンとしてのPERFORMANCE_SCHEMA
も自身の情報を多少収集しています。この情報にはSHOW ENGINE performance_schema STATUS
でアクセスできます(SHOW ENGINE INNODB STATUS
のPERFORMANCE_SCHEMA
ストレージエンジン版)。
mysql57> SHOW ENGINE PERFORMANCE_SCHEMA STATUS;
+--------------------+-------------------------------------------------------------+----------+
| Type | Name | Status |
+--------------------+-------------------------------------------------------------+----------+
| performance_schema | events_waits_current.size | 176 |
| performance_schema | events_waits_current.count | 1536 |
| performance_schema | events_waits_history.size | 176 |
| performance_schema | events_waits_history.count | 2560 |
| performance_schema | events_waits_history.memory | 450560 |
..
| performance_schema | performance_schema.memory | 94739320 |
+--------------------+-------------------------------------------------------------+----------+
229 rows in set (0.00 sec)
各テーブルに記録されている統計の個数、記録された回数、記録に利用しているメモリー量などを確認できます。特に最後の1行「パフォーマンススキーマ全体でどれくらいのメモリーを利用しているか」は注意して見るようにしましょう。
sysとは
sysは、パフォーマンススキーマの情報を見やすくするためのビューやストアドファンクション、ストアドプロシージャの集まりです。名前空間としてsys
データベースを利用するため、もっぱら sys
スキーマ(MySQLではスキーマとデータベースは同じものを指す)と呼ばれることが多いです。パフォーマンススキーマを前提としたビューが主な機能なので、performance_schema = OFF
の状態ではほとんどのビューは結果を返しません。
MySQL 5.7ではデータベースを初期化(mysqld --initialize
)した時点でsys
データベースが作成されますが、MySQL 5.6ではGitHubのmysql-sysリポジトリーからスクリプトをダウンロードして実行する必要があります(ビュー、関数、ストアドプロシージャなのでインストールというよりはCREATE VIEW
などが並んだsqlスクリプトを実行するだけ)。また、MySQL 5.5以前(そもそもパフォーマンススキーマが実装されていなかった)には対応していません。
sysのセットアップ(MySQL 5.6向け)
MySQL 5.6向けのセットアップ手順は以下の通りです。URLやファイル名などは2016/07/12現在のもので、将来変更になる可能性があります。
$ git clone https://github.com/mysql/mysql-sys.git
Initialized empty Git repository in /root/mysql-sys/.git/
remote: Counting objects: 3009, done.
remote: Total 3009 (delta 0), reused 0 (delta 0), pack-reused 3008
Receiving objects: 100% (3009/3009), 1.17 MiB | 466 KiB/s, done.
Resolving deltas: 100% (1768/1768), done.
$ cd mysql-sys
$ mysql -uroot -p < sys_56.sql
$ mysql -uroot -p
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.01 sec)
sys_56.sql
を実行する際、mysql
コマンドラインクライアントに-v
オプションを与えて実行すると、画面にステートメントを出力できます(-v
オプションなしでそのまま実行すると、何も表示されずにプロンプトが返ってくる)。 sys_56.sql
はセッションのバイナリーログをオフにするため、マスターで実行してもスレーブにsys
データベースは作成されません。
sysの便利機能
sysには多くのビュー、ストアドファンクション、ストアドプロシージャが存在します。完全なリストはドキュメントで確認できますが、ここでは筆者が実運用上で役立てているいくつかの機能を紹介します。
sys.statement_analysis
statement_analysis
は、performance_schema.events_statements_summary_by_digest
の内容を人間が見やすい形に整形したビューです。
mysql> SELECT * FROM statement_analysis\G
..
*************************** 2. row ***************************
query: SELECT `c` FROM `sbtest1` WHERE `id` = ?
db: sbtest
full_scan:
exec_count: 23890
err_count: 0
warn_count: 0
total_latency: 2.36 s
max_latency: 521.15 us
avg_latency: 98.74 us
lock_latency: 778.65 ms
rows_sent: 23890
rows_sent_avg: 1
rows_examined: 23890
rows_examined_avg: 1
rows_affected: 0
rows_affected_avg: 0
tmp_tables: 0
tmp_disk_tables: 0
rows_sorted: 0
sort_merge_passes: 0
digest: 80295d1d2720d4515b05d648e8caa82f
first_seen: 2016-07-12 17:04:40
last_seen: 2016-07-12 17:04:53
..
query
カラムは文字数によってsys.format_statement
関数で切り詰めて表示されます(切り詰められたくない場合はx$statement_analysis
テーブルを参照。statement_analysis
に限らず、sys
データベースのビューにはx$
接頭辞を持つものが対として存在しており、それらは切り詰めの関数を通さなくなっている)。表示される単位は「ダイジェスト」であり、例えばSELECT c FROM sbtest1 WHERE id = 1
とSELECT c FROM sbtest1 WHERE id = 2
は定数部分がノーマライズされて同じダイジェストを持ちます。
記録されている値は累積の統計値のためスローログのように時系列変化を追うことはできませんが、スローログに記録されないような「1回ずつの実行時間は閾値未満だが、多くの回数実行されて累計の処理時間が長いもの」や「テンポラリーテーブルをDisk上に出力する必要があったもの」、「rows_examined
に対してrows_sent
が圧倒的に少なく(x$statement_analysis
を利用する場合、 ORDER BY rows_examined / rows_sent DESC
でソートできる)インデックス効率が悪そうなもの」などを抽出できます。
sys.innodb_lock_waits
innodb_lock_waits
は、information_schema
のinnodb_trx
、innodb_locks
、innodb_lock_waits
を結合したビューです(information_schema
を利用しているため、パフォーマンススキーマの有効/無効に関わらず利用できる)。
mysql57> SELECT * FROM innodb_lock_waits\G
*************************** 1. row ***************************
wait_started: 2016-07-12 17:49:06
wait_age: 00:00:13
wait_age_secs: 13
locked_table: `d1`.`user`
locked_index: PRIMARY
locked_type: RECORD
waiting_trx_id: 8063
waiting_trx_started: 2016-07-12 17:49:06
waiting_trx_age: 00:00:13
waiting_trx_rows_locked: 1
waiting_trx_rows_modified: 0
waiting_pid: 320
waiting_query: SELECT * FROM user LIMIT 3 FOR UPDATE
waiting_lock_id: 8063:146:3:2
waiting_lock_mode: X
blocking_trx_id: 8062
blocking_pid: 321
blocking_query: NULL
blocking_lock_id: 8062:146:3:2
blocking_lock_mode: X
blocking_trx_started: 2016-07-12 17:49:06
blocking_trx_age: 00:00:13
blocking_trx_rows_locked: 3
blocking_trx_rows_modified: 0
sql_kill_blocking_query: KILL QUERY 321
sql_kill_blocking_connection: KILL 321
1 row in set (0.01 sec)
上記のように、待っているクエリー、待たせているクエリーを一覧できます。InnoDBのロックを確認するといえばMySQL InnoDBにおけるロック競合の解析手順 - SH2の日記が有名ですが、同等以上の情報を確認できるビューを利用できるのは嬉しいところです(筆者は必要になるたび、このブログのステートメントからビューを作っていた)。
sys.ps_truncate_all_tables
ps_truncate_all_tables
は、パフォーマンススキーマに蓄積された統計情報をリセットするためのストアドプロシージャです。パフォーマンススキーマに蓄積された情報はテーブルをTRUNCATE
することでリセットができることは先に触れましたが、 performance_schema
データベース(記録系のテーブルのみ。setup_*
は対象外)の全てのテーブルにTRUNCATE
を実行することで統計情報をクリアします(関数の名前通りの動き)。
mysql> CALL sys.ps_truncate_all_tables(0);
+---------------------+
| summary |
+---------------------+
| Truncated 44 tables |
+---------------------+
1 row in set (0.01 sec)
Query OK, 0 rows affected (0.01 sec)
引数には"0"または"1"を指定します。"1"を指定した場合、全てのTRUNCATE
ステートメントが実行と同時に表示されます。やっていることがシンプルなだけに胸を張って「これがsys
の機能の1つ」というのは若干憚られますが、 筆者は"a set of objects that helps DBAs and developers interpret data collected by the Performance Schema"(https://dev.mysql.com/doc/refman/5.7/en/sys-schema.html)というsys
の目標に非常によく沿った関数だと考えています。
その他のsysのオブジェクト
sys
データベースにはいくつものビューが格納されていますが、ほとんどのビューは名前からその用途が想像できます。statement_analysis
を参照してWHERE
でフィルターをかけたり、ORDER BY
でソートし直しても特に不便はないため、筆者はあまり別のビューは利用していません。
sys
データベースにはいくつものビューが格納されていますが、ほとんどのビューは名前からその用途が想像できます。statement_analysis
を参照してWHERE
でフィルターをかけたり、ORDER BY
でソートし直したりしても特に不便はないため、筆者はあまり別のビューは利用していません。
sys
のビューの多くはx$接頭辞がついた同じ名前のビューを持っています。パフォーマンススキーマはもともとナノ秒(ns)単位でレイテンシーを記録しますが、ナノ秒は人間がパッと見るには不向きな単位です。そこでsysのビューでは原則sys.format_timeストアドファンクションを利用して、1000ナノ秒を1マイクロ秒(1000ns= 1us)に、1000マイクロ秒を1ミリ秒(1000us = 1ms)に、1000ミリ秒を1秒(1000ms = 1s)に、60秒を1分(60s = 1m)に、60分を1時間(60m = 1h)に、24時間を1日(24h = 1d)に、7日を1週(7d = 1w)に変換して表示します(筆者としては"分"以降の単位は余計なお世話だと考えるが)。
この変換は見る分には便利ですが、変換後の値は「単位まで含めた文字列」として扱われてしまうため、ソートしようとした場合に問題になります(例えば"1ms"と"1us"をORDER BY DESC比較すると、"u"の方が"m"よりも後に来るため、"1us", "1ms"の順にソートされてしまう)。このような場合はx$接頭辞のビューを利用するとナノ秒のまま整数値として扱えるので、WHERE句、ORDERBY句のみをx$ビューで処理してdigestカラムなどでJOIN
し、表示はx$でない方を利用すると見やすくなります。
mysql> SELECT statement_analysis.* FROM x$statement_analysis JOIN statement_analysis USING(digest) ORDER BY x$statement_analysis.avg_latency DESC LIMIT 3;
+-------------------------------------------------------------------+------+-----------+------------+-----------+------------+---------------+-------------+-------------+--------------+-----------+---------------+---------------+-------------------+---------------+-------------------+------------+-----------------+-------------+-------------------+----------------------------------+---------------------+---------------------+
| query | db | full_scan | exec_count | err_count | warn_count | total_latency | max_latency | avg_latency | lock_latency | rows_sent | rows_sent_avg | rows_examined | rows_examined_avg | rows_affected | rows_affected_avg | tmp_tables | tmp_disk_tables | rows_sorted | sort_merge_passes | digest | first_seen | last_seen |
+-------------------------------------------------------------------+------+-----------+------------+-----------+------------+---------------+-------------+-------------+--------------+-----------+---------------+---------------+-------------------+---------------+-------------------+------------+-----------------+-------------+-------------------+----------------------------------+---------------------+---------------------+
| SELECT * FROM SYSTEM_USER LIMIT ? FOR UPDATE | d1 | | 4 | 1 | 0 | 1.00 h | 1.00 h | 15.00 m | 2.02 ms | 9 | 2 | 9 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | d5474c388bde037685b236bfd3b09573 | 2016-07-12 17:48:54 | 2016-07-12 18:49:07 |
| DROP SCHEMA `d1` | NULL | | 1 | 0 | 0 | 46.29 ms | 46.29 ms | 46.29 ms | 41.94 ms | 0 | 0 | 0 | 0 | 6 | 6 | 0 | 0 | 0 | 0 | aa246c9d2acb3f947ac3baf335bae205 | 2016-07-15 19:46:08 | 2016-07-15 19:46:08 |
| SELECT `sys` . `format_stateme ... cy` , `sys` . `format_time` ( | sys | * | 3 | 0 | 0 | 66.79 ms | 36.17 ms | 22.26 ms | 28.07 ms | 93 | 31 | 187 | 62 | 0 | 0 | 0 | 0 | 93 | 0 | 537d3840a8bc9fee4fd63febaab85365 | 2016-07-19 09:01:28 | 2016-07-19 09:08:24 |
+-------------------------------------------------------------------+------+-----------+------------+-----------+------------+---------------+-------------+-------------+--------------+-----------+---------------+---------------+-------------------+---------------+-------------------+------------+-----------------+-------------+-------------------+----------------------------------+---------------------+---------------------+
3 rows in set (0.03 sec)
まとめ
パフォーマンススキーマはMySQL 5.6で大きく機能、性能が改善されました。MySQL 5.6以降ではデフォルトでONになっています。パフォーマンススキーマの設定はperformance_schema
データベースのsetup_*
テーブルにUPDATE
することで変更できます。パフォーマンススキーマのデフォルト設定(performance_schema.setup_*
テーブルの初期値)のままでも改善に役立つ情報が蓄積されるため、特に理由がなければ有効にしておくことをお勧めします。
sys
はパフォーマンススキーマの情報を見やすくするためのビューやストアドプロシージャの集合です。パフォーマンススキーマ、sys
ともSQLでアクセスできるため、SELECT
を工夫することで様々な情報にアクセスしたりデータを保管したりできます。
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- 再現性のあるスロークエリーには「SHOW PROFILE」を試してみよう
- MySQL 5.6での機能強化点(その2)- NoSQL APIとパフォーマンス・スキーマ
- MySQLのリアルタイムモニタリングに「innotop」
- DBドキュメント出力とMEBのためのGUI、次期版6.1の新機能を紹介
- 機械学習で利用できる「トレーニング」「推論」「説明」のSQL関数を理解しよう
- MySQL 5.6での機能強化点(その1)- パフォーマンスと使い勝手を大きく向上
- MySQLのチューニングを戦う方へ
- MySQL5.6- さらなる機能追加とNoSQL
- SQL実行計画の疑問解決には「とりあえずEXPLAIN」しよう
- MySQL Clusterのバックアップ/リストアの具体例