首先讓我們指出最重要的事情:第二個查詢不是有效的SQL查詢,因爲它使用MySQL GROUP BY extensions。當您關閉這個MySQL擴展與
SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
,那麼你會得到一個錯誤這樣的:
ERROR 1463 (42000): non-grouping field 'id' is used in HAVING clause
所以,你應該用WHERE
條款。
但現在到你的實際問題。我從你的測量中認爲,在「id」字段中有一個索引。因爲HAVING
對分組數據有效(應該可以),所以沒有可以使用的索引。我在這裏有一個約有120萬行的MySQL表。 A HAVING
對索引整數字段的查詢在第一次運行時需要16秒,並且在連續調用時仍然約爲0.6秒,而使用WHERE
的查詢僅需要0.04秒。
使用EXPLAIN
,MySQL會告訴你,它不使用索引:
EXPLAIN SELECT id, title, resum FROM film HAVING id =56;
舉個例子,這裏有來自EXPLAIN
的結果查詢我的表:
mysql> EXPLAIN SELECT id, Title FROM `test` HAVING id = 4374354;
+----+-------------+----------+------+---------------+------+---------+------+---------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+------+---------------+------+---------+------+---------+-------+
| 1 | SIMPLE | test | ALL | NULL | NULL | NULL | NULL | 1201750 | |
+----+-------------+----------+------+---------------+------+---------+------+---------+-------+
您會看到,「鍵」字段顯示「NULL」,告訴您沒有使用任何索引。 「rows」字段告訴你,MySQL遍歷1201750(全部)行。
mysql> EXPLAIN SELECT id, Title FROM `test` WHERE id = 4374354;
+----+-------------+----------+-------+---------------+---------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+-------+---------------+---------+---------+-------+------+-------+
| 1 | SIMPLE | test | const | PRIMARY | PRIMARY | 4 | const | 1 | |
+----+-------------+----------+-------+---------------+---------+---------+-------+------+-------+
在另一方面,對於EXPLAIN
WHERE
告訴我們,它使用了「主要」指標,因此它只是讀取單行,導致更快的響應。