WHERE実行順。
ども、あにごん@お料理してない時間はお勉強タイムです。
先週後半は
とあるスクリプト中の、MySQLにSQL文発行してるところで、
えらく遅い部分があったので、高速化しようと、うだうだ悩んでいたんだけど。
ご存知の通り、SQLは私の弱点でして
はてさて、どう対応したものか…と思ってたら
そーいやぁ、以前、誰かにSQL文のWHERE句の実行順について
「下から実行説」を聞かされたなぁ…と思ったりして。
だけど、それが一体どういう条件で
どのDBが、それにあたるんだか、サッパリ記憶になかったので
大きな声で呼んでみた。
せーのっ
ぐーぐるせんせーっ!
ふぉーふぉふぉふぉふぉー
ワシを呼んだかの?…と、差し出してくれたのはこのページ。
なるほど、Oracle の話で、かつインデックスの関係ない場合ですか。
かくして、MySQLは、素直に上から実行(左から実行とも言う)するんだな、って事で
以下のSQL文の実行速度について、ついでにちょっと調査してみる。
CREATE TABLE test_table (
flag tinyint(1),
name varchar(16)
);
これに100件データを insert しまして、その中の1レコードだけを
INSERT INTO test_table VALUES(0, 'anigon');
にしました。
ほんで、以下の3パターンのSELECT文を発行するんだけど。
・Aパターン(一番速いと勝手に思ってるパターン)
SELECT name
FROM test_table
WHERE flag = 0
AND name = 'anigon';
・Bパターン(遅いだろうなと思ってるパターン)
SELECT name
FROM test_table
WHERE name = 'anigon'
AND flag = 0;
・Cパターン(めっさ遅いだろうな、と思ってるパターン)
SELECT name
FROM test_table
WHERE name like '%anigon%'
AND flag = 0;
で、先ず人に聞くと「実行計画見たらどうよ?」と答えられるんだけど
explain で見ても、3パターンとも何も変わらないように見えてしまうんだな、これが。
へなちょこ野郎あにやまんには、この時点でSQL苦手意識で早くもゲンナリ(笑)
・Aパターン
+----+-------------+------------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | test_table | ALL | NULL | NULL | NULL | NULL | 100 | Using where |
+----+-------------+------------+------+---------------+------+---------+------+------+-------------+
・Bパターン
+----+-------------+------------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | test_table | ALL | NULL | NULL | NULL | NULL | 100 | Using where |
+----+-------------+------------+------+---------------+------+---------+------+------+-------------+
・Cパターン
+----+-------------+------------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | test_table | ALL | NULL | NULL | NULL | NULL | 100 | Using where |
+----+-------------+------------+------+---------------+------+---------+------+------+-------------+
仕方ないので、benchmark 取るべー…って、実行してみるんだけど
1つのパターンを10回ずつ実行しても、数字が安定しなくって
うーん、レコード100件程度じゃ、何も変わらないような気がしてくるのでした…orz
えーい、じゃあ、1000件でどうだ!…って、これくらいじゃ差が出ないのでして
うーむうーむ。じゃあ、5000件で、どうよ!
・Aパターン
5.62 sec〜7.21 sec
・Bパターン
5.54 sec〜7.18 sec
・Cパターン
5.47 sec〜7.31 sec
・・・うーん、何かたぶん計測すべきSQL文とか条件が
よろしくないんだろうか…。
うーんうーん。ますます苦手意識がついちゃいますね(苦笑)