MySQL スロークエリ設定とスレッド分析マニュアル

本ドキュメントは、開発者および運用担当者がMySQLのスロークエリログを迅速に設定し、低速なSQLを分析し、データベース実行時のスレッドブロッキングや負荷問題をトラブルシューティングするためのガイドです。

  1. スロークエリログの有効化

スロークエリの有効化には主に2つの方法があります:一時有効(再起動不要だが、再起動後に無効化)と永続有効(設定ファイル変更、再起動必須)。

1.1 一時的な有効化 (実行時)

本番環境で問題を一時的に調査し、データベースを再起動したくない場合に適用します。

SQL

-- 1. スロークエリログスイッチをONに
SET GLOBAL slow_query_log = 'ON';

-- 2. スロークエリ閾値を設定(単位:秒)
-- 例:1秒を超えるクエリを記録
SET GLOBAL long_query_time = 1;

-- 3. (任意)インデックス未使用のクエリを記録
SET GLOBAL log_queries_not_using_indexes = 'ON';

注意: long_query_time を変更しても、新規接続にのみ有効です。現在のセッションで即時反映させるには、SET long_query_time = 1; を実行する必要があります。

1.2 永続的な有効化 (設定ファイル)

長期監視に適しています。my.cnf(Linux)またはmy.ini(Windows)ファイルを修正します。

[mysqld] セクションに以下を追加または修正します:

Ini, TOML

[mysqld]
# スロークエリログを有効化
slow_query_log = 1

# スロークエリログファイルパス(絶対パス推奨)
slow_query_log_file = /var/lib/mysql/mysql-slow.log

# スロークエリ閾値(秒)
long_query_time = 1

# (任意)インデックス未使用のクエリを記録
log_queries_not_using_indexes = 1

修正後、MySQLサービスを再起動してください: systemctl restart mysqld

1.3 設定の確認

以下SQLを実行して設定が有効になったか確認します:

SQL

SHOW VARIABLES LIKE '%slow_query%';
SHOW VARIABLES LIKE 'long_query_time';

  1. スロークエリの分析と表示

スロークエリログはテキストファイルとして直接確認できますが、公式のmysqldumpslowツールを使用して集約分析することもできます。これが最も一般的な方法です。

2.1 主なパラメータ説明 (mysqldumpslow)

  • -s: ソート方式 (Sort)
  • c: アクセス回数 (Count)
  • t: クエリ実行時間 (Time)
  • l: ロック時間 (Lock time)
  • r: 返された行数 (Rows)
  • at: 平均クエリ時間
  • -t: 上位何件を表示するか (Top)
  • -g: 正規表現マッチング (Grep)

2.2 主な分析コマンド例

ターミナル(Shell)で実行:

mysqldumpslow -s t -t 10 /var/lib/mysql/mysql-slow.log	

2. 「アクセス回数」でソートし、最も頻繁に実行される低速SQLを特定

Bash

mysqldumpslow -s c -t 10 /var/lib/mysql/mysql-slow.log

3. 「平均時間」でソートし、特定のテーブル名(例: user)を含むSQLを検索

Bash

mysqldumpslow -s at -t 10 -g "user" /var/lib/mysql/mysql-slow.log

  1. スレッドと負荷問題のトラブルシューティング

データベースのCPU使用率が急上昇または応答が遅延しているが、スロークエリログがまだ生成されていない(クエリがまだ終了していない)場合、スレッド状態をリアルタイムで確認する必要があります。

3.1 現在実行中のスレッドの確認

SHOW PROCESSLISTコマンドを使用します。

SQL

-- 現在の接続の上位100スレッドを表示
SHOW PROCESSLIST;

-- すべてのスレッドを表示(完全なSQL)
SHOW FULL PROCESSLIST;

3.2 注目すべきフィールド

**フィールド** **説明** **異常状態 (State)**
**Id** スレッドID Kill操作に使用
**User** 実行ユーザー -
**Time** 経過時間(秒) 値が大きい場合は注意が必要
**Command** コマンドタイプ Query(クエリ実行中)、Sleep(アイドル状態)
**State** **現在の状態(重要)** Locked(ロック中)、Sending data(大量データ読み込み中)、Copying to tmp table(一時テーブルが大きすぎる)
**Info** SQL文 実行中の具体的なSQL文

3.3 Information Schemaを使用した高度なフィルタリング

スレッドが非常に多い場合、SHOW PROCESSLISTでは確認しづらいため、システムテーブルを直接クエリします:

SQL

-- 実行時間が30秒を超える非Sleepスレッドをクエリ
SELECT * FROM information_schema.processlist 
WHERE command != 'Sleep' 
AND time > 30 
ORDER BY time DESC;

3.4 停止したスレッドの強制終了

特定のSQL(IDが1234など)がデッドロックを引き起こしたりリソースを消費したりしている場合、強制終了できます:

SQL

KILL 1234;

  1. よくある問題のトラブルシューティング速查表

**現象** **考えられる原因** **調査方法**
**CPU 100%** 複雑なSQLが計算中または無限ループ top -cでmysqlプロセスを確認 → SHOW FULL PROCESSLISTStateSending dataまたはStatisticsの高負荷SQLを探す。
**I/O待機時間が高い** フルテーブルスキャン、一時ディスク書き込み スロークエリログを確認し、Rows\_examinedRows\_sentを大幅に上回る文を注目;StateCopying to tmp table on diskを確認。
**接続数が上限に達** 低速SQLの蓄積による接続解放遅延 SHOW VARIABLES LIKE 'max\_connections';で現在の接続数と比較。

タグ: MySQL スロークエリ パフォーマンスチューニング データベース監視 SQL分析

8月10日 23:00 投稿