PostgreSQL:使用join和group by查询花费的时间太长

时间:2019-10-02 07:40:28

标签: sql postgresql performance join indexing

我有两个看起来像这样的表:

表_1:

<div id="app">
  <p>{{ message }}</p>
  <jk v-model="add"></jk>
</div>

表_2:

-----------------------------------
| ID  |  customer_id  |   city    |
-----------------------------------
| 0   |  E100         |  Sydney   |
-----------------------------------
| 1   |  E200         |  Toronto  | 
-----------------------------------
| 2   |  E300         |  New York |
-----------------------------------

我要做的是,汇总每个不同的customer_id的所有收据。 结果表应如下所示:

----------------------------------------------
| customer_id  |    timestamp   |   receipt  |
----------------------------------------------
|    E200      |  '2019-03-25'  |    200$    | 
----------------------------------------------
|    E300      |  '2019-03-26'  |    300$    |
----------------------------------------------
|    E300      |  '2019-03-26'  |    100$    |
----------------------------------------------
|    E100      |  '2019-03-27'  |     50$    | 
----------------------------------------------
|    E100      |  '2019-03-28'  |     50$    |
----------------------------------------------
|    E100      |  '2019-03-29'  |     50$    |
----------------------------------------------

为了实现这一点,我使用以下PostgreSQL查询:

----------------------------------------------
| customer_id |    city    |   sum(receipt)  |
----------------------------------------------
|    E100     |  Sydney    |      150$       |
----------------------------------------------
|    E200     |  Toronto   |      200$       | 
----------------------------------------------
|    E300     |  New York  |      400$       |
----------------------------------------------

但是,由于table_2具有超过300mio行,而table_1具有129行, 查询花费的时间太长(我不知道确切要花多长时间->对这个查询的EXPLAIN ANALYZE也没有完成)。我想INNER JOIN是这里的瓶颈(如果我错了,请纠正我)? 但是我确实知道查询做对了,因为我尝试只过滤一天(而不是一周)来进行过滤。

我的问题是如何加快此查询的速度。我已经考虑过添加这样的索引:

SELECT a.customer_id, a.city, SUM(b.receipt) 
FROM public.table_1 a 
INNER JOIN public.table_2 b
   ON a.customer_id = b.customer_id
   WHERE b.timestamp > '2019-03-25 00:00:00' 
   AND b.timestamp < '2019-04-01 00:00:00' 
GROUP BY a.customer_id, a.city

但是此查询也将永远进行下去。

有什么建议吗?

2 个答案:

答案 0 :(得分:2)

尝试先聚集,然后加入:

SELECT a.customer_id, a.city, b.receipt_sum
FROM public.table_1 a 
 JOIN (
   SELECT t2.customer_id, sum(t2.receipt) as receipt_sum
   FROM public.table_2 t2
   WHERE t2.timestamp > '2019-03-25 00:00:00' 
     AND t2.timestamp < '2019-04-01 00:00:00' 
   GROUP BY t2.customer_id
 ) b ON a.customer_id = b.customer_id

答案 1 :(得分:1)

让我们尝试在加入之前先过滤table_2表。

SELECT a.customer_id, a.city, SUM(b.receipt) 
FROM public.table_1 a
INNER JOIN 
(SELECT receipt, customer_id FROM public.table_2 
    WHERE timestamp > '2019-03-25 00:00:00' 
    AND timestamp < '2019-04-01 00:00:00') b ON a.customer_id = b.customer_id
GROUP BY a.customer_id, a.city