php - 如何避免在查询中包含子句?

标签 php mysql sql

我正在处理这个成功运行的查询

select 
hash,
SUM(DATE(TIMESTAMP) = CURDATE()) as today,
sum(DATE(TIMESTAMP) between DATE_SUB(CURDATE( ), INTERVAL 7 DAY) and  DATE_SUB(CURDATE( ), INTERVAL 1 DAY)) as last_week

from behaviour

group by hash
having last_week > 0 and today > last_week
order by today desc

我正在努力优化它。

我正在尝试避免 last_week>0 进入 having 子句,但运气不佳。我收到“无效使用群组功能”

select 
hash,
SUM(DATE(TIMESTAMP) = CURDATE()) as today,
sum(DATE(TIMESTAMP) between DATE_SUB(CURDATE( ), INTERVAL 7 DAY) and  DATE_SUB(CURDATE( ), INTERVAL 1 DAY)) as last_week

from behaviour
where 
and (sum(DATE(TIMESTAMP) between DATE_SUB(CURDATE( ), INTERVAL 4 DAY) and  DATE_SUB(CURDATE( ), INTERVAL 1 DAY)) > 0)

group by hash
having today > last_week
order by today desc

如何优化它?因为在大表中执行大约需要 1 分钟。

最佳答案

您想在进行聚合之前进行过滤:

select hash,
       sum(DATE(TIMESTAMP) = CURDATE()) as today,
       sum(DATE(TIMESTAMP) between DATE_SUB(CURDATE( ), INTERVAL 7 DAY) and DATE_SUB(CURDATE( ), INTERVAL 1 DAY)) as last_week
from behaviour
where timestamp >= curdate() - interval 7 day
      timestamp < curdate() + interval 1 day
group by hash
having today > last_week and last_week > 0
order by today desc;

这减少了group by 所需的数据量——这应该会显着提高性能。您可以使用 (timestamp, hash) 上的索引进一步提高性能。

您仍然需要 having 子句,因为您需要对结果进行额外的过滤。不过,性能提升来自聚合之前的过滤。

关于php - 如何避免在查询中包含子句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48599053/

相关文章:

mysql - 在另一个 SQL 查询的循环中运行一个 SQL 查询?

php - 按时间戳对记录排序,但首先列出指定的 ID

mysql - 在sql中按月名分组

php - 计数 SQL 语法 COUNT(value) 多列

javascript - 如何使用云存储分段上传音乐/视频(适用于 Laravel)?

php - 将多维数组转换为单维数组

php - Laravel 递归地在 "app/database/migrations"文件夹上运行迁移

php - 为什么 mysql_fetch_object 在 class_name 为 null 时失败,即使这是默认值?

MySQL 日期从月份和日期格式中减去

php - 批量删除大量文件