MySQLではSELECT文の実行計画を分析するためのEXPLAINコマンドが提供されています。このコマンドにより、SELECT文の実行詳細情報を取得でき、開発者はそれに基づいてパフォーマンスチューニングを行うことができます。
テスト用テーブルの作成
CREATE TABLE `customer_data` (
`customer_id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`full_name` VARCHAR(50) NOT NULL DEFAULT '',
`age` INT(11) DEFAULT NULL,
PRIMARY KEY (`customer_id`),
KEY `name_index` (`full_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO customer_data (full_name, age) VALUES ('tanaka', 25);
INSERT INTO customer_data (full_name, age) VALUES ('sato', 30);
INSERT INTO customer_data (full_name, age) VALUES ('suzuki', 35);
CREATE TABLE `order_records` (
`order_id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`customer_id` BIGINT(20) DEFAULT NULL,
`product_code` VARCHAR(50) NOT NULL DEFAULT '',
`manufacturer` VARCHAR(30) DEFAULT NULL,
PRIMARY KEY (`order_id`),
KEY `customer_product_index` (`customer_id`, `product_code`, `manufacturer`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO order_records (customer_id, product_code, manufacturer) VALUES (1, 'A001', 'ABC');
INSERT INTO order_records (customer_id, product_code, manufacturer) VALUES (1, 'A002', 'DEF');
INSERT INTO order_records (customer_id, product_code, manufacturer) VALUES (2, 'B001', 'ABC');
EXPLAINの出力形式
EXPLAINコマンドの出力例:
mysql> EXPLAIN SELECT * FROM customer_data WHERE customer_id = 1\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: customer_data
partitions: NULL
type: const
possible_keys: PRIMARY
key: PRIMARY
key_len: 8
ref: const
rows: 1
filtered: 100.00
Extra: NULL
重要なカラムの解説:
- select_type: クエリタイプ(SIMPLE/UNION/SUBQUERYなど)
- type: 接続タイプ(const/ref/rangeなど)
- key_len: 使用したインデックスのバイト数
- rows: スキャン予測行数
- Extra: 補足情報(Using filesort/Using indexなど)
typeカラムの評価基準
クエリ性能の判断に重要なtypeカラムの値の順位:
ALL < index < range < ref < eq_ref < const < system
インデックス使用状況の確認
以下のクエリはインデックスを使用しない:
mysql> EXPLAIN SELECT * FROM customer_data WHERE age = 30\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: customer_data
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 3
filtered: 33.33
Extra: Using where
インデックスを使用する例:
mysql> EXPLAIN SELECT * FROM customer_data WHERE full_name = 'sato'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: customer_data
partitions: NULL
type: ref
possible_keys: name_index
key: name_index
key_len: 153
ref: const
rows: 1
filtered: 100.00
Extra: Using index
補足情報の解釈
- Using filesort: インデックスでソートできない場合に発生
- Using index: インデックスのみでクエリが実行可能
- Using temporary: 一時テーブルが必要な場合に表示