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( 我如何简化这些冗余代码。
这会影响性能吗?
可能没有任何有意义的方式。 查询的性能通常由检索和处理数据所做的工作主导。 这通常比内置函数的开销昂贵得多(尽管有一些例外,例如正则表达式可能相当昂贵(。
MySQL允许在GROUP BY
中使用列别名。 所以一个有效的"简化"是:
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()
可能是一个极其昂贵的函数,您可能会发现最后两种解决方案中的任何一种都更快。 此外,如果数据至少有几千行,您可能只会看到对性能的影响。 无论这些问题如何,通常都会快速处理琐碎的小表(几十行或几百行(。
-
如果小时列具有整数值,请尝试此列。我们只能删除一次冗余。
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)