使用WHERE和HAVING查询响应时间

时间:2013-09-30 10:30:33

标签: mysql query-optimization where having

我有一个简单的SQL请求:

SELECT id, title, resum
FROM film
WHERE id = 56 ;

此请求的响应时间几乎等于0.0009秒

然而,相同的查询,使用Having Clause:

SELECT id, title, resum
FROM film
HAVING id =56 ;

根据第一个请求(0.0049秒)给出如此大的响应时间。

第一个请求更加优化,但是,为什么? 你能告诉我造成这种巨大差异的原因吗?

最诚挚的问候。

1 个答案:

答案 0 :(得分:1)

首先,让我们说明最重要的事情:您的第二个查询不是有效的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对分组数据起作用(应该起作用),所以没有它可以使用的索引。我这里有一个MySQL表,大约有120万行。对索引整数字段的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 |       |
+----+-------------+----------+------+---------------+------+---------+------+---------+-------+

你看,“key”字段表示“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的{​​{1}}告诉我们,它使用“PRIMARY”索引,因此它只需读取一行,从而产生更快的响应。 / p>