時々、頭の中で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_date と c1 にインデックスを貼ってあります。
説明のため、ベースとなる実行計画を示します。
idx1 インデックスから to_date と c1 の条件にマッチするレコードを引き当ててます。Extra は NULL です。
これは違和感のない実行計画です。
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 をつけると、Extra に Using 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 は出てない。
ベースのクエリにソートが加わるのみなので、Extra に Using 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表示上のだけの問題だった可能性もありそう。