如何避免让子句进入查询?

时间:2018-02-03 15:39:24

标签: 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没有运气的条款。我得到了“无效使用群组功能”

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分钟。

1 个答案:

答案 0 :(得分:3)

您希望在进行聚合之前过滤

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子句,因为您需要在结果上添加其他过滤器。但是,性能增益来自聚合之前的过滤。