MySQL/パフォーマンスチューニング/EXPLAIN
パフォーマンスチューニングの第一歩。
SELECTクエリの解析を行う。
UPDATEやDELETEの解析はできないので、その場合はSELECT+WHERE句で代用しよう。
書式
例
テスト用データ
id int(8) NOT NULL,
name varchar(20),
age smallint(1),
PRIMARY KEY (id),
KEY index_text (name)
) TYPE=InnoDB;
insert into MYTABLE values (2, ’2′, ’2′);
insert into MYTABLE values (3, ’3′, ’3′);
insert into MYTABLE values (4, ’4′, ’4′);
insert into MYTABLE values (5, ’5′, ’5′);
insert into MYTABLE values (6, ’6′, ’6′);
insert into MYTABLE values (7, ’7′, ’7′);
insert into MYTABLE values (8, ’8′, ’8′);
insert into MYTABLE values (9, ’9′, ’9′);
insert into MYTABLE values (10, ’10′, ’10′);
insert into MYTABLE values (11, ’11′, ’11′);
insert into MYTABLE values (12, ’12′, ’12′);
insert into MYTABLE values (13, ’13′, ’13′);
insert into MYTABLE values (14, ’14′, ’14′);
insert into MYTABLE values (15, ’15′, ’15′);
insert into MYTABLE values (16, ’16′, ’16′);
insert into MYTABLE values (17, ’17′, ’17′);
insert into MYTABLE values (18, ’18′, ’18′);
insert into MYTABLE values (19, ’19′, ’19′);
insert into MYTABLE values (20, ’20′, ’20′);
type:テーブルスキャンのタイプを最適化する
ALLはフルスキャンなので、一番パフォーマンスが悪い。
目標とするtypeを理想的な順序で。
1.const
検索結果が1件。オプティマイザにより定数として扱われるため超高速。
+———+——-+—————+———+———+——-+——+——-+
| table | type | possible_keys | key | key_len | ref | rows | Extra |
+———+——-+—————+———+———+——-+——+——-+
| MYTABLE | const | PRIMARY | PRIMARY | 4 | const | 1 | |
+———+——-+—————+———+———+——-+——+——-+
1 row in set (0.00 sec)
2.ref系
eq_ref, ref, ref_or_nullがある。ユニークではないインデックスを利用して結果を検索。
+———+——+—————+————+———+——-+——+————+
| table | type | possible_keys | key | key_len | ref | rows | Extra |
+———+——+—————+————+———+——-+——+————+
| MYTABLE | ref | index_text | index_text | 21 | const | 1 | where used |
+———+——+—————+————+———+——-+——+————+
1 row in set (0.00 sec)
3.range
インデックスを利用した範囲検索。
+———+——-+—————+————+———+——+——+————+
| table | type | possible_keys | key | key_len | ref | rows | Extra |
+———+——-+—————+————+———+——+——+————+
| MYTABLE | range | index_text | index_text | 21 | NULL | 3 | where used |
+———+——-+—————+————+———+——+——+————+
1 row in set (0.00 sec)
古いバージョンのMySQL(3.x, 4.xくらいまで?)の場合、1テーブルにつき1つのインデックスしか利用されないため、SQL改善時には注意が必要。
不恰好なSQLに書き換える(e.g.無理やりUNIONで結合)か、ある程度妥協しなければなりません。
4.ALL
フルスキャン。rows=行数。
+———+——+—————+——+———+——+——+——-+
| table | type | possible_keys | key | key_len | ref | rows | Extra |
+———+——+—————+——+———+——+——+——-+
| MYTABLE | ALL | NULL | NULL | NULL | NULL | 20 | |
+———+——+—————+——+———+——+——+——-+
1 row in set (0.00 sec)
rows:スキャン対象行数
rowsの項目は、SELECTによって結果を取得するために、スキャンしなければならない行数を表している。
この行数をできる限り小さくすることを目標とする。
同じ結果となるSQLでも、記述方法によって効率が変わってきます。
単純な例
(idが1〜6まであるとして、)
と、
では、同じ結果が取得できるにもかかわらず、前者はrowsが3、後者はrowsが6となります。
Extra:付加情報
以下のようなものがあります。
ファイルソートと一時表の利用を避けるようにがんばりましょう。Using indexとwhere usedはウレシイ。
-where used
-Distinct
-Not exists
-Using filesort
-Using index
-Using temporary
MySQL/パフォーマンスチューニング/インデックス
インデックス追加
テーブルにインデックスを追加する。
書式
例
mysql> alter table USER add index idx_user_1 (userName, delFlag);
Query OK, 1427 rows affected (0.19 sec)
Records: 1427 Duplicates: 0 Warnings: 0
インデックス削除
テーブルに設定されているインデックスを削除する。
書式
例
Query OK, 428 rows affected (0.05 sec)
Records: 428 Duplicates: 0 Warnings: 0
インデックス参照
テーブルに設定されているインデックスの一覧を表示する。
書式
例
—————+———-+———-+———-+———+———–+——-+——+—-+———+——-
Table|NonUnique|Key_name |SeqInIndex|ColumnName|Collation|Cardinality|SubPart|Packed|Null|IndexType|Comment
—————+———-+———-+———-+———+———–+——-+——+—-+———+——-
USER | 0|PRIMARY | 1|id |A | 428| NULL|NULL | |BTREE |
USER | 1|idx_user_1| 1|userName |A | 428| NULL|NULL | |BTREE |
USER | 1|idx_user_1| 2|delFlag |A | 2| NULL|NULL | |BTREE |
—————+———-+———-+———-+———+———–+——-+——+—-+———+——-

