At first, let's state the most important thing: Your second query isn't a valid SQL query as it uses the MySQL GROUP BY extensions. When you switch off this MySQL extension with
SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
then you'll get an error like this:
ERROR 1463 (42000): non-grouping field 'id' is used in HAVING clause
So, you should really use the WHERE
clause.
But now to your actual question. I assume from your measurements, that there is an index on the "id" field. Because HAVING
works (should work) on grouped data, there's no index it could use. I've got a MySQL table here with about 1.2 million rows. A HAVING
query on an indexed integer field takes 16 seconds on its first run and still about 0.6 seconds on consecutive calls, whereas the query using WHERE
just takes 0.04 seconds.
Using EXPLAIN
, MySQL will tell you that it doesn't use an index:
EXPLAIN SELECT id, title, resum FROM film HAVING id =56;
As an example, here are the results from EXPLAIN
for the queries on my table:
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 | |
+----+-------------+----------+------+---------------+------+---------+------+---------+-------+
You see, the "key" field states "NULL", telling you that there isn't any index used. The "rows" field tells you instead, that MySQL traverses 1201750 (all) rows.
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 | |
+----+-------------+----------+-------+---------------+---------+---------+-------+------+-------+
On the other hand, the EXPLAIN
for WHERE
tells us, that it uses the "PRIMARY" index and thus it just has to read a single row, resulting in a much faster response.