在mysql中限制查询数据

时间:2017-02-24 21:26:32

标签: mysql sql

几年后我回到mysql并遇到了问题。我有一个有效的查询,但我对如何更好地优化它感到迷茫。

以下是查询:

select
    u.id as 'User',
    count(distinct tr.id) as Trips,
    count(distinct ti.id) as 'Trip Items'
from
    users u
inner join
    user_emails ue on u.id = ue.user_id
inner join
    trips tr on tr.user_id = u.id
inner join
    trip_items ti on ti.trip_id = tr.id
where
    ue.verified = true and ue.is_primary = true
and
    tr.created_at between '2017-02-01 00:00:00' and '2017-02-01 00:59:59'
group by 1
having Trips < 30

我基本上需要计算所有旅行和旅行项目..但仅适用于在给定日期范围内有30次或更少旅行的用户。现在,我正在通过用户对结果进行分组,然后执行“拥有”来实现这一目标。我在非索引字段(created_at)上查看数百万条结果。理想情况下,我想获得一排总行程和总行程项目。但在查询期间仍然应用“用户少于30次旅行”。这可能吗? :)

只是一个快速编辑,我已经尝试了解其他解决方案,但我有点迷失在我应该寻找的东西上。我不是在寻找解决方案,也许只是“去检查一下并尝试一下”。

1 个答案:

答案 0 :(得分:1)

count(distinct)可能很贵。尝试在执行join之前聚合。我认为以下工作(假设不同的旅行之间不共享项目):

select u.id as `User`, tr.Trips, tr.items
from users u inner join
     user_emails ue
     on u.id = ue.user_id inner join
     (select tr.user_id, count(*) as Trips, sum(items) as items
      from trips tr join
           (select ti.trip_id, count(*) as items
            from trip_items ti 
            group by ti.trip_id
           ) ti
           on ti.trip_id = tr.id
       where tr.created_at >= '2017-02-01' and tr.created_at < '2017-02-01 01:00:00'
      group by tr.user_id
      having trips < 30
     ) tr
     on tr.user_id = u.id inner join
where ue.verified = true and ue.is_primary = true
group by 1