mita2 database life

主にMySQLに関するメモです

MySQL 8.0 で謎のEXPLAIN結果が出なくなってた

時々、頭の中でMySQLの気持ちになって考えた実行計画と違うものが出力されるときがあるんですよね。 まぁ、実用上、問題になることはなかったので、「MySQL ヨクワカランなー」と思って、スルーしてました。

ところが、最近、MySQL 8.0 をいじってたら、イメージしている実行計画が表示されてることに気づきました。ワイワイ!

MySQL 5.7 の謎の Index Condition Pushdown 表示

今回のお題のテーブルはこちら(Employees Sample DBに 適当にカラム c1 を追加したもの)

mysql> SHOW CREATE TABLE salaries \G
*************************** 1. row ***************************
       Table: salaries
Create Table: CREATE TABLE `salaries` (
  `emp_no` int(11) NOT NULL,
  `salary` int(11) NOT NULL,
  `from_date` date NOT NULL,
  `to_date` date NOT NULL,
  `c1` int(11) DEFAULT NULL,
  PRIMARY KEY (`emp_no`,`from_date`),
  KEY `idx1` (`to_date`,`c1`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

to_datec1 にインデックスを貼ってあります。

説明のため、ベースとなる実行計画を示します。 idx1 インデックスから to_datec1 の条件にマッチするレコードを引き当ててます。ExtraNULL です。 これは違和感のない実行計画です。

mysql> EXPLAIN SELECT * FROM salaries 
  WHERE to_date = '2010-10-10' AND c1 = 0 \G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: salaries
   partitions: NULL
         type: ref
possible_keys: idx1
          key: idx1
      key_len: 8
          ref: const,const
         rows: 1
     filtered: 100.00
        Extra: NULL
1 row in set, 1 warning (0.00 sec)

このクエリに ORDER BY salary をつけると、ExtraUsing index condition が出現します。

mysql> EXPLAIN SELECT * FROM salaries
   WHERE to_date = '2010-10-10' AND c1 = 0 ORDER BY salary\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: salaries
   partitions: NULL
         type: ref
possible_keys: idx1
          key: idx1
      key_len: 8
          ref: const,const
         rows: 1
     filtered: 100.00
        Extra: Using index condition; Using filesort
1 row in set, 1 warning (0.00 sec)

to_date = '2010-10-10' AND c1 = 0 は、等価比較なので、インデックスコンディションプッシュダウン で解決する必要はありません。 その証拠にベースのクエリでは、Using index condtion は出てない。

ベースのクエリにソートが加わるのみなので、ExtraUsing filesort だけが追加されるんじゃないの・・・?

MySQL 8.0 の実行計画

同じ条件で、MySQL 8.0 の実行計画を見てみます。

mysql> EXPLAIN SELECT * FROM salaries
    ->    WHERE to_date = '2010-10-10' AND c1 = 0 ORDER BY salary\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: salaries
   partitions: NULL
         type: ref
possible_keys: idx1
          key: idx1
      key_len: 8
          ref: const,const
         rows: 1
     filtered: 100.00
        Extra: Using filesort
1 row in set, 1 warning (0.00 sec)

謎の Using index condtion がなくなったぞー👏👏👏

ちなみに、実行速度の変化は、未確認です。そもそも、EXPLAIN表示上のだけの問題だった可能性もありそう。