本番環境とローカル開発環境の環境差異(Aurora, MariaDB)でクエリの実行速度に驚くほど差が出たのでメモ
AuroraはガワはMYSQLでも中身はかなり違うとは聞いていたけど…
実行環境
Aurora: 5.6.10a
MariaDB: 5.5.52
テーブル情報(共通)
INDEXが貼られているのはPKとcolumn_Dのみ
1 2 3 4 5 6 |
| sample_table | CREATE TABLE `sample_table` ( // カラム定義省略 PRIMARY KEY (`id`), KEY `idx_sample_table_column_D` (`column_D`), ) ENGINE=InnoDB AUTO_INCREMENT=21259587 DEFAULT CHARSET=utf8 |
実行クエリ
column_C=0とcolumn_C<>0のテーブルをINDEXのないcolumn_Bで自己結合し、結合に失敗したレコードを抽出
クエリ自体が酷いのはご愛嬌…
1 2 3 4 5 6 7 8 9 |
SELECT COUNT(*), column_A FROM sample_table LEFT JOIN (SELECT column_B FROM sample_table WHERE column_C &lt;&gt; 0 AND column_D = '2018-04-25') AS mem ON sample_table.column_B = mem.column_B WHERE column_D = '2018-04-25' AND column_C = 0 AND mem.column_B IS NULL GROUP BY column_A, column_E, column_F LIMIT 200 OFFSET 1800 //一部省略 |
実装したやからをしばき倒したい_:(´ཀ`」 ∠):
実行計画
Aurora
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
---|---|---|---|---|---|---|---|---|---|
1 | PRIMARY | sample_table | ref | idx_sample_table_column_D | idx_sample_table_column_D | 3 | const | 67448 | Using where; Using temporary; Using filesort |
1 | PRIMARY | ref | 122 | lp_main.sample_table.column_B | 10 | Using where; Not exists; Using index |
|||
2 | DERIVED | sample_table | ref | idx_sample_table_column_D | idx_sample_table_column_D | 3 | const | 67448 | Using where |
MariaDB
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | sample_table | ref | idx_sample_table_column_D | idx_sample_table_column_D | 3 | const | 67448 | Using where Using temporary Using filesort |
1 | SIMPLE | sample_table | ref | idx_sample_table_column_D, idx_sample_table_column_B |
idx_sample_table_column_B | 122 | lp_main.sample_table.column_B | 1 | Using where |
実行結果
Aurora: 1.66sec
MaraDB: 120sec以上 (session kill!)
AuroraではINDEXのない結合部が分割された上、Not Existで処理されているため非常に高速化している