MySQLクエリ最適化のためのEXPLAINコマンド

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: 一時テーブルが必要な場合に表示

タグ: MySQL EXPLAIN sql最適化 インデックス クエリ解析

6月9日 18:33 投稿