如何减少单个查询中的冗余 MySQL 函数调用?

How to reduce redundant MySQL function calls in a single query?

SELECT hour(datetime), COUNT(animal_id)
FROM animal_outs 
WHERE hour(datetime) > 8 AND hour(datetime) < 20
GROUP BY hour(datetime)

我正在学习SQL。我在查询中调用了四次 hour(datetime)。我很好奇 1) 这种冗余是否会影响性能,以及 2) 如何简化这种冗余代码。

  • 如果小时列有整数值那么试试这个one.We可以只删除一次冗余。

    SELECT hour ,COUNT(animal_id) FROM animal_outs WHERE hour BETWEEN 8 AND 20 GROUP BY hour

  • 如果小时是日期格式,请尝试以下代码。

SELECT DATEPART(HH,hour) ,COUNT(animal_id) FROM animal_outs WHERE DATEPART(HH,hour) BETWEEN 8 AND 20 GROUP BY DATEPART(HH,hour)

Does this affect performance?

可能没有任何意义。查询的性能通常取决于为检索和处理数据所做的工作。这通常比内置函数的开销要昂贵得多(尽管有一些例外,例如可能相当昂贵的正则表达式)。

MySQL 允许在 GROUP BY 中使用列别名。所以一个有效的 "simplification" 是:

SELECT hour(datetime) as hh, COUNT(animal_id)
FROM animal_outs 
WHERE hour(datetime) > 8 AND hour(datetime) < 20
GROUP BY hh;

可能会使事情变得更糟的两个版本可能看起来对您来说更简单,但事实并非如此。第一种是使用 having:

SELECT hour(datetime) as hh, COUNT(animal_id)
FROM animal_outs 
GROUP BY hh
HAVING hh > 8 AND hh < 20

从技术上讲,这可以满足您的需求。但是因为它在 聚合之后过滤 ,所以它在 GROUP BY 上做额外的工作。这可能超过不打电话给 hour().

节省的任何费用

另一种方法是子查询:

SELECT hh, COUNT(animal_id)
FROM (SELECT hour(datetime) as hh, animal_id
      FROM animal_outs 
     ) ao
WHERE hh > 8 AND hh < 20
GROUP BY hh;

在大多数数据库中,这会满足您的要求。它 可能 在 MySQL 的最新版本中。但是,MySQL 在 FROM 子句中有一种令人讨厌的实现(即写入磁盘)子查询的趋势。这增加了额外的开销——再一次,可能比对 hour().

的额外调用更多

注意:hour() 可能是一个非常昂贵的函数,您可能会发现最后两个解决方案中的任何一个都更快。此外,如果您的数据至少有几千行,您可能只会看到对性能的影响。无论这些问题如何,通常都可以快速处理非常小的表(几十或几百行)。