来自subselect的SQL聚合函数太慢了

时间:2017-02-16 11:59:14

标签: mysql sql

此查询需要太多时间..

 SELECT sum(res.opportunities_sum) as opportunities_sum,
        res.traffic_source_id, sum(res.ad_request_sum) as ad_request_sum, 
        sum(res.ad_impression_sum) as ad_impression_sum, sum(res.ad_start_sum) as ad_start_sum
 FROM 
 (
     SELECT sum(ev.opportunities) as opportunities_sum,
            ev.traffic_source_id,
            (select sum(ad_request) FROM events_ad_source a
             where a.event_id = ev.id) as ad_request_sum, 
            (select sum(ad_impression) FROM events_ad_source a
             where a.event_id = ev.id) as ad_impression_sum, 
            (select sum(ad_start) FROM events_ad_source a
             where a.event_id = ev.id) as ad_start_sum 
     FROM events ev 
     inner join user_agents
         on ev.user_agent_id = user_agents.id 
     WHERE ev.traffic_source_id IN (6,1,5,10,9,8,7) AND
           ev.date BETWEEN '01-01-2017' AND '02-16-2017'
     GROUP BY ev.traffic_source_id, ev.id 
     ORDER BY ev.traffic_source_id
) as res
GROUP BY res.traffic_source_id  

但是内部查询结果在不到一秒的时间内取得...

我需要优化此查询..

编辑: 我有3张桌子

事件

events_ad_source

user_agents

当我尝试在事件和events_ad_source之间加入

events.opportunities的总和返回按events_ad_source中的行数计算的结果,

导致事件中的每一行,

events_ad_source

中有很多行

(我现在无法添加表格定义)

----我运行EXPLAIN - 这是结果----

QUERY PLAN                                                                                                                                                      |
----------------------------------------------------------------------------------------------------------------------------------------------------------------|
GroupAggregate  (cost=12804.13..58865668.76 rows=200 width=36)                                                                                                  |
  Group Key: ev.traffic_source_id                                                                                                                               |
  ->  GroupAggregate  (cost=12804.13..58864073.65 rows=70716 width=12)                                                                                          |
        Group Key: ev.traffic_source_id, ev.id                                                                                                                  |
        ->  Sort  (cost=12804.13..12980.92 rows=70716 width=12)                                                                                                 |
              Sort Key: ev.traffic_source_id, ev.id                                                                                                             |
              ->  Hash Join  (cost=1.36..7108.04 rows=70716 width=12)                                                                                           |
                    Hash Cond: (ev.user_agent_id = user_agents.id)                                                                                              |
                    ->  Seq Scan on events ev  (cost=0.00..5802.86 rows=159110 width=16)                                                                        |
                          Filter: ((date >= '2017-01-01'::date) AND (date <= '2017-02-16'::date) AND (traffic_source_id = ANY ('{6,1,5,10,9,8,7}'::integer[]))) |
                    ->  Hash  (cost=1.16..1.16 rows=16 width=4)                                                                                                 |
                          ->  Seq Scan on user_agents  (cost=0.00..1.16 rows=16 width=4)                                                                        |
        SubPlan 1                                                                                                                                               |
          ->  Aggregate  (cost=277.39..277.40 rows=1 width=4)                                                                                                   |
                ->  Seq Scan on events_ad_source a  (cost=0.00..277.39 rows=1 width=4)                                                                          |
                      Filter: (event_id = ev.id)                                                                                                                |
        SubPlan 2                                                                                                                                               |
          ->  Aggregate  (cost=277.39..277.40 rows=1 width=4)                                                                                                   |
                ->  Seq Scan on events_ad_source a_1  (cost=0.00..277.39 rows=1 width=4)                                                                        |
                      Filter: (event_id = ev.id)                                                                                                                |
        SubPlan 3                                                                                                                                               |
          ->  Aggregate  (cost=277.39..277.40 rows=1 width=4)                                                                                                   |
                ->  Seq Scan on events_ad_source a_2  (cost=0.00..277.39 rows=1 width=4)                                                                        |
                      Filter: (event_id = ev.id)                                                                                                                |

------------- TABLE DATA ---------------

活动:

id     |traffic_source_id |opportunities |date       |
-------|------------------|--------------|-----------|
318192 |5                 |1             |2017-02-12 |
318193 |5                 |1             |2017-02-12 |
318194 |5                 |1             |2017-02-12 |
318195 |5                 |3             |2017-02-12 |
318196 |5                 |4             |2017-02-12 |
318197 |5                 |1             |2017-02-12 |
318198 |5                 |1             |2017-02-12 |

EVENTS_AD_SOURCE:

id    |event_id |traffic_source_id |ad_request |
------|---------|------------------|-----------|
17997 |318195   |5                 |1          |
17993 |318192   |5                 |1          |
17994 |318192   |5                 |1          |
17995 |318192   |5                 |1          |
17996 |318193   |5                 |1          |
17998 |318196   |5                 |4          |
17999 |318197   |5                 |1          |
18000 |318198   |5                 |1          |
18001 |318198   |5                 |1          |

SO(机会),SUM(AD_REQUEST)的结果 应该

12 | 12

1 个答案:

答案 0 :(得分:0)

按照您的代码方式,您只需执行子选择..

你可以减少第二级子选择

SELECT sum(res.opportunities_sum) as opportunities_sum,
        res.traffic_source_id, sum(res.ad_request_sum) as ad_request_sum, 
        sum(res.ad_impression_sum) as ad_impression_sum, sum(res.ad_start_sum) as ad_start_sum
 FROM 
 (
   SELECT 
        sum(ev.opportunities) as opportunities_sum
      , ev.traffic_source_id
      , t1.ad_request_sum 
      , t1.ad_impression_sum
      , t1.ad_start_sum
    from FROM events ev 
    LEFT JOIN  ( select  
        event_id 
     ,  sum(ad_request) as ad_request_sum
     ,  sum(ad_impression) as ad_impression_sum
     , sum(ad_start) as ad_start_sum 
    FROM events_ad_source a
    group by event_id
    ) t1 on t1.event_id = ev.id
    inner join user_agents on ev.user_agent_id = user_agents.id 
   WHERE ev.traffic_source_id IN (6,1,5,10,9,8,7) AND
         ev.date BETWEEN '01-01-2017' AND '02-16-2017'
   GROUP BY ev.traffic_source_id, ev.id 
   ORDER BY ev.traffic_source_id
) as res
GROUP BY res.traffic_source_id  

但是看起来你的外部选择的事实是对同一组的已聚合函数执行聚合函数 你可以通过外部选择获得结果

   SELECT 
        sum(ev.opportunities) as opportunities_sum
      , ev.traffic_source_id
      , t1.ad_request_sum 
      , t1.ad_impression_sum
      , t1.ad_start_sum
    from FROM events ev 
    LEFT JOIN  ( select  
        event_id 
     ,  sum(ad_request) as ad_request_sum
     ,  sum(ad_impression) as ad_impression_sum
     , sum(ad_start) as ad_start_sum 
    FROM events_ad_source a
    group by event_id
    ) t1 on t1.event_id = ev.id
    inner join user_agents on ev.user_agent_id = user_agents.id 
   WHERE ev.traffic_source_id IN (6,1,5,10,9,8,7) AND
         ev.date BETWEEN '01-01-2017' AND '02-16-2017'
   GROUP BY ev.traffic_source_id, ev.id 
   ORDER BY ev.traffic_source_id