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

标签 mysql sql refactoring sql-tuning

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) 如何简化这些冗余代码。

最佳答案

Does this affect performance?

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

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() 可能是一个极其昂贵的函数,您可能会发现最后两个解决方案中的任何一个都更快。此外,如果数据至少有几千行,您可能只会看到对性能的影响。不管这些问题如何,通常都可以快速处理很小的表(几十行或几百行)。

关于mysql - 如何减少单个查询中冗余的MySQL函数调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59233034/

相关文章:

mysql - INSERT INTO 基于 WHERE in double JOIN 的结果

php - 使用内连接从多个表中删除

mysql - Wordpress SQL - 多个 WHERE 子句

mysql - 无法在 MySql 中将 varchar 转换为 datetime

ruby-on-rails - 多个 before_action 调用错误的代码风格吗?

php - Mysql 编辑用户下的订单

android - SignalR:从数据库向用户ID发送消息

javascript - 谷歌图表将标题显示为标签

go - 按类型划分的功能?怎么重构呢?

java - 如何命名一个公开序列化和反序列化/编码解码方法的类