【问题标题】:Query response time with WHERE and HAVING使用 WHERE 和 HAVING 查询响应时间
【发布时间】:2013-09-30 10:30:33
【问题描述】:

我有一个简单的 SQL 请求:

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

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

然而,同样的查询,使用了从句:

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

与第一个请求(0.0049 秒)相比,响应时间如此之长。

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

最好的问候。

【问题讨论】:

    标签: mysql query-optimization where having


    【解决方案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 |       |
    +----+-------------+----------+-------+---------------+---------+---------+-------+------+-------+
    

    另一方面,WHEREEXPLAIN 告诉我们,它使用“PRIMARY”索引,因此它只需要读取一行,从而获得更快的响应。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多