Home > EXPLAINのEXTRAとTYPE

EXPLAINのEXTRAとTYPE

  • July 3, 2007 5:09 PM

  1. EXPLAIN

    テーブルは、EXPLAIN によって表示される順序で読み取られる。出力結果の内容は以下の通り。 

    項目 意味
    id クエリ内部において SELECT が使用する連続した ID
    select_type SELECT の種類 (サブクエリ、UNION など)
    type 使用する結合型
    key 使用するインデックス
    key_len 使用したキーの長さ
    ref 検索に使用するフィールド
    rows クエリの各ステップを実行するために確認が必要な行の数

    rows の積は、クエリを実行するために確認する必要がある行の総数

    Extra テーブルの結合方法に関する追加情報
  1. EXTRA
    1. EXTRAにあるとうれしい値
      • Using index: 最適。インデックスツリーの探索で処理を完了できる。
      • Using where: 適切。これが欠けている場合は、テーブルの全ての行が参照される。
      • Distinct: DISTINCTを指定した場合?前のテーブルの組み合わせごとに1行が特定される場合。
      • Not exists: LEFT JOIN利用時に一部の余分な行の探索を省略できた場合?
          • 例:
            t2のidにNOT NULLが設定された時の、以下のSQL文
            SELECT * FROM t1 LEFT JOIN t2 ON t1.id=t2.id
            WHERE t2.id IS NULL;
            -
    2. EXTRAにあるとうれしくない値
      • Using filesort: インデックスを作成していないカラムでソートしている場合などに発生。
      • Using temporary: 一時テーブルが必要。ORDER BYとGROUP BYで指定しているカラムが異なる場合など。
      • Range checked for each record: JOINに使用しているインデックスのサイズが違う場合など。
  2. TYPE
 
 
    TYPE 意味
    system テーブルがMyISAMで、行を一つしか持たない場合
    const テーブルに、一致する行が一行のみの場合
    eq_ref 前のテーブルの組み合わせごとに一行が、このテーブルから読み取られる場合
    ref / ref_or_null 前のテーブルの組み合わせごとに複数行が、このテーブルから読み取られる場合
    unique_subquery サブクエリの結果が一意のインデックスでカバーされる場合
    index_subquery サブクエリの結果が、一意で無いインデックスを利用している場合
    range 指定した範囲内の行だけ読み取る場合
    index インデックスツリー全体がスキャンされる場合
    all テーブル全体がスキャンされる場合
 

    望ましい順序

    1. system

    テーブルが行を一つしか持たない場合 

      mysql> show create table t3¥G

      *************************** 1. row ***************************

             Table: t3

      Create Table: CREATE TABLE `t3` (

        `a` int(11) NOT NULL,

        PRIMARY KEY  (`a`)

      ) ENGINE=MyISAM DEFAULT CHARSET=latin1

      1 row in set (0.00 sec) 

      mysql> select * from t3;

      +---+

      | a |

      +---+

      | 0 |

      +---+

      1 row in set (0.00 sec) 

      mysql> explain select * from t3\G

      *************************** 1. row ***************************

                 id: 1

        select_type: SIMPLE

              table: t3

               type: system

      possible_keys: NULL

                key: NULL

            key_len: NULL

                ref: NULL

               rows: 1

              Extra:

      1 row in set (0.00 sec)

 

    但しInnoDBでは行数の情報を保持していないので、テーブルが一行しか無い場合もsystemにはならない。 

      mysql> show create table t2¥G

      *************************** 1. row ***************************

             Table: t2

      Create Table: CREATE TABLE `t2` (

        `a` int(11) NOT NULL,

        PRIMARY KEY  (`a`)

      ) ENGINE=InnoDB DEFAULT CHARSET=latin1

      1 row in set (0.00 sec) 

      mysql> select * from t2;

      +---+

      | a |

      +---+

      | 0 |

      +---+

      1 row in set (0.00 sec) 

      mysql> explain select * from t2 where a=0\G

      *************************** 1. row ***************************

                 id: 1

        select_type: SIMPLE

              table: t2

               type: const

      possible_keys: PRIMARY

                key: PRIMARY

            key_len: 4

                ref: const

               rows: 1

              Extra: Using index

      1 row in set (0.00 sec)

    1. const

    テーブルに、一致する行が一行のみの場合

    一行のみであるため、オプティマイザは定数と見なす 

     
      mysql> show create table t2¥G

      *************************** 1. row ***************************

             Table: t2

      Create Table: CREATE TABLE `t2` (

        `a` int(11) NOT NULL,

        PRIMARY KEY  (`a`)

      ) ENGINE=InnoDB DEFAULT CHARSET=latin1

      1 row in set (0.00 sec) 

      mysql> select * from t2;

      +---+

      | a |

      +---+

      | 0 |

      | 1 |

      +---+

      2 rows in set (0.00 sec) 

      mysql> explain select * from t2 where a=0\G

      *************************** 1. row ***************************

                 id: 1

      select_type: SIMPLE

              table: t2

               type: const

      possible_keys: PRIMARY

                key: PRIMARY

            key_len: 4

                ref: const

               rows: 1

              Extra: Using index

      1 row in set (0.00 sec) 

    1. eq_ref
 

    前のテーブルの組み合わせごとに一行が、このテーブルから読み取られる場合 

t4
a (PK) b
1 0
2 0
3 1
 
t2
a (PK)
0
1
2
 
 

     
     

      mysql> show create table t4¥G

      *************************** 1. row ***************************

             Table: t4

      Create Table: CREATE TABLE `t4` (

        `a` int(11) NOT NULL auto_increment,

        `b` int(11) default NULL,

        PRIMARY KEY  (`a`)

      ) ENGINE=InnoDB DEFAULT CHARSET=latin1

      1 row in set (0.00 sec) 

      mysql> show create table t2\G

      *************************** 1. row ***************************

             Table: t2

      Create Table: CREATE TABLE `t2` (

        `a` int(11) NOT NULL,

        PRIMARY KEY  (`a`)

      ) ENGINE=InnoDB DEFAULT CHARSET=latin1

      1 row in set (0.00 sec) 

      mysql> select * from t4;

      +---+------+

      | a | b    |

      +---+------+

      | 1 |    0 |

      | 2 |    0 |

      | 3 |    1 |

      +---+------+

      3 rows in set (0.00 sec) 

      mysql> select * from t2;

      +---+

      | a |

      +---+

      | 0 |

      | 1 |

      | 2 |

      +---+

      3 rows in set (0.00 sec) 

      mysql> explain select * from t4,t2 where t4.b=t2.a\G

      *************************** 1. row ***************************

                 id: 1

        select_type: SIMPLE

              table: t4

               type: ALL

      possible_keys: NULL

                key: NULL

            key_len: NULL

                ref: NULL

               rows: 3

              Extra:

      *************************** 2. row ***************************

                 id: 1

        select_type: SIMPLE

              table: t2

               type: eq_ref

      possible_keys: PRIMARY

                key: PRIMARY

            key_len: 4

                ref: ona.t4.b

               rows: 1

              Extra: Using index

      2 rows in set (0.00 sec) 

    1. ref / ref_or_null

    前のテーブルの組み合わせごとに複数行が、このテーブルから読み取られる場合

    NULL値を含む場合がref_or_null 

    ref

      mysql> show create table t4¥G

      *************************** 1. row ***************************

             Table: t4

      Create Table: CREATE TABLE `t4` (

        `a` int(11) NOT NULL auto_increment,

        `b` int(11) default NULL,

        PRIMARY KEY  (`a`)

      ) ENGINE=InnoDB DEFAULT CHARSET=latin1

      1 row in set (0.00 sec) 

      mysql> show create table t1\G

      *************************** 1. row ***************************

             Table: t1

      Create Table: CREATE TABLE `t1` (

        `a` int(11) default NULL,

        KEY `idx` (`a`)

      ) ENGINE=InnoDB DEFAULT CHARSET=latin1

      1 row in set (0.00 sec) 

      mysql> select * from t4;

      +---+------+

      | a | b    |

      +---+------+

      | 1 |    0 |

      | 2 |    0 |

      | 3 |    1 |

      +---+------+

      3 rows in set (0.00 sec) 

      mysql> select * from t1;

      +------+

      | a    |

      +------+

      |    0 |

      |    0 |

      |    1 |

      +------+

      3 rows in set (0.00 sec) 

      mysql> explain select * from t4,t1 where t4.b=t1.a\G

      *************************** 1. row ***************************

                 id: 1

        select_type: SIMPLE

              table: t4

               type: ALL

      possible_keys: NULL

                key: NULL

            key_len: NULL

                ref: NULL

               rows: 3

              Extra:

      *************************** 2. row ***************************

                 id: 1

        select_type: SIMPLE

              table: t1

               type: ref

      possible_keys: idx

                key: idx

            key_len: 5

                ref: ona.t4.b

               rows: 1

              Extra: Using where; Using index

      2 rows in set (0.00 sec)

    1. unique_subquery

    サブクエリの結果が一意のインデックスでカバーされる場合 

      mysql> show create table t2¥G

      *************************** 1. row ***************************

             Table: t2

      Create Table: CREATE TABLE `t2` (

        `a` int(11) NOT NULL,

        PRIMARY KEY  (`a`)

      ) ENGINE=InnoDB DEFAULT CHARSET=latin1

      1 row in set (0.00 sec) 

      mysql> show create table t5\G

      *************************** 1. row ***************************

             Table: t5

      Create Table: CREATE TABLE `t5` (

        `a` int(11) NOT NULL auto_increment,

        `b` int(11) default NULL,

        PRIMARY KEY  (`a`),

        KEY `idx` (`b`)

      ) ENGINE=InnoDB DEFAULT CHARSET=latin1

      1 row in set (0.00 sec) 

      mysql> select * from t2;

      +---+

      | a |

      +---+

      | 0 |

      | 1 |

      | 2 |

      +---+

      3 rows in set (0.00 sec) 

      mysql> select * from t5;

      +---+------+

      | a | b    |

      +---+------+

      | 6 | NULL |

      | 1 |    0 |

      | 2 |    0 |

      | 3 |    1 |

      | 4 |    2 |

      | 5 |    2 |

      +---+------+

      6 rows in set (0.00 sec) 
       

      mysql> explain select * from t2 where a in(select a from t5 where b=t2.a)\G

      *************************** 1. row ***************************

                 id: 1

        select_type: PRIMARY

              table: t2

               type: index

      possible_keys: NULL

                key: PRIMARY

            key_len: 4

                ref: NULL

               rows: 3

              Extra: Using where; Using index

      *************************** 2. row ***************************

                 id: 2

        select_type: DEPENDENT SUBQUERY

              table: t5

               type: unique_subquery

      possible_keys: PRIMARY,idx

                key: PRIMARY

            key_len: 4

                ref: func

               rows: 1

              Extra: Using index; Using where

      2 rows in set (0.00 sec)

    1. index_subquery

    サブクエリの結果が、一意で無いインデックスを利用している場合 

      mysql> show create table t2¥G

      *************************** 1. row ***************************

             Table: t2

      Create Table: CREATE TABLE `t2` (

        `a` int(11) NOT NULL,

        PRIMARY KEY  (`a`)

      ) ENGINE=InnoDB DEFAULT CHARSET=latin1

      1 row in set (0.00 sec) 

      mysql> show create table t5\G

      *************************** 1. row ***************************

             Table: t5

      Create Table: CREATE TABLE `t5` (

        `a` int(11) NOT NULL auto_increment,

        `b` int(11) default NULL,

        PRIMARY KEY  (`a`),

        KEY `idx` (`b`)

      ) ENGINE=InnoDB DEFAULT CHARSET=latin1

      1 row in set (0.00 sec) 

      mysql> select * from t2;

      +---+

      | a |

      +---+

      | 0 |

      | 1 |

      | 2 |

      +---+

      3 rows in set (0.00 sec) 

      mysql> select * from t5;

      +---+------+

      | a | b    |

      +---+------+

      | 6 | NULL |

      | 1 |    0 |

      | 2 |    0 |

      | 3 |    1 |

      | 4 |    2 |

      | 5 |    2 |

      +---+------+

      6 rows in set (0.00 sec) 
       

      mysql> explain select * from t2 where a in(select b from t5 where b<4)\G

      *************************** 1. row ***************************

                 id: 1

        select_type: PRIMARY

              table: t2

               type: index

      possible_keys: NULL

                key: PRIMARY

            key_len: 4

                ref: NULL

               rows: 3

              Extra: Using where; Using index

      *************************** 2. row ***************************

                 id: 2

        select_type: DEPENDENT SUBQUERY

              table: t5

               type: index_subquery

      possible_keys: idx

                key: idx

            key_len: 5

                ref: func

               rows: 1

              Extra: Using index; Using where

      2 rows in set (0.00 sec)

    1. range

    指定した範囲内の行だけ読み取る場合 

      mysql> show create table t5¥G

      *************************** 1. row ***************************

             Table: t5

      Create Table: CREATE TABLE `t5` (

        `a` int(11) NOT NULL auto_increment,

        `b` int(11) default NULL,

        PRIMARY KEY  (`a`),

        KEY `idx` (`b`)

      ) ENGINE=InnoDB DEFAULT CHARSET=latin1

      1 row in set (0.00 sec) 

      mysql> select * from t5;

      +---+------+

      | a | b    |

      +---+------+

      | 6 | NULL |

      | 1 |    0 |

      | 2 |    0 |

      | 3 |    1 |

      | 4 |    2 |

      | 5 |    2 |

      +---+------+

      6 rows in set (0.00 sec) 
       

      mysql> explain select * from t5 where a between 2 and 5\G

      *************************** 1. row ***************************

                 id: 1

        select_type: SIMPLE

              table: t5

               type: range

      possible_keys: PRIMARY

                key: PRIMARY

            key_len: 4

                ref: NULL

               rows: 3

              Extra: Using where

      1 row in set (0.00 sec)

    1. index

    インデックスツリー全体がスキャンされる場合 

      mysql> show create table t4¥G

      *************************** 1. row ***************************

             Table: t4

      Create Table: CREATE TABLE `t4` (

        `a` int(11) NOT NULL auto_increment,

        `b` int(11) default NULL,

        PRIMARY KEY  (`a`)

      ) ENGINE=InnoDB DEFAULT CHARSET=latin1

      1 row in set (0.00 sec) 

      mysql> select * from t4;

      +---+------+

      | a | b    |

      +---+------+

      | 1 |    0 |

      | 2 |   0 |

      | 3 |    1 |

      | 4 | NULL |

      +---+------+

      4 rows in set (0.01 sec) 

      mysql> explain select a from t4\G

      *************************** 1. row ***************************

                 id: 1

        select_type: SIMPLE

              table: t4

               type: index

      possible_keys: NULL

                key: PRIMARY

            key_len: 4

                ref: NULL

               rows: 4

              Extra: Using index

      1 row in set (0.00 sec)

    1. all

    テーブル全体がスキャンされる場合 

      mysql> show create table t4¥G

      *************************** 1. row ***************************

             Table: t4

      Create Table: CREATE TABLE `t4` (

        `a` int(11) NOT NULL auto_increment,

        `b` int(11) default NULL,

        PRIMARY KEY  (`a`)

      ) ENGINE=InnoDB DEFAULT CHARSET=latin1

      1 row in set (0.00 sec) 

      mysql> select * from t4;

      +---+------+

      | a | b    |

      +---+------+

      | 1 |    0 |

      | 2 |    0 |

      | 3 |    1 |

      | 4 | NULL |

      +---+------+

      4 rows in set (0.01 sec) 
       

      mysql> explain select b from t4\G

      *************************** 1. row ***************************

                 id: 1

        select_type: SIMPLE

              table: t4

               type: ALL

      possible_keys: NULL

                key: NULL

            key_len: NULL

                ref: NULL

               rows: 4

              Extra:

      1 row in set (0.00 sec)

関連エントリー

Home > EXPLAINのEXTRAとTYPE

Search
Feeds

Return to page top