【发布时间】:2020-01-31 11:23:52
【问题描述】:
我有两张表,如下所示:
table_1:
-----------------------------------
| ID | customer_id | city |
-----------------------------------
| 0 | E100 | Sydney |
-----------------------------------
| 1 | E200 | Toronto |
-----------------------------------
| 2 | E300 | New York |
-----------------------------------
table_2:
----------------------------------------------
| 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$ |
----------------------------------------------
我想要做的是总结每个不同 customer_id 的所有收据。 结果表应如下所示:
----------------------------------------------
| customer_id | city | sum(receipt) |
----------------------------------------------
| E100 | Sydney | 150$ |
----------------------------------------------
| E200 | Toronto | 200$ |
----------------------------------------------
| E300 | New York | 400$ |
----------------------------------------------
为了实现这一点,我使用以下 PostgreSQL 查询:
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
但是,由于 table_2 有超过 300mio 行,而 table_1 有 129 行, 查询花费的时间太长(我不知道究竟需要多长时间 -> EXPLAIN ANALYZE 对此查询也没有完成)。我猜 INNER JOIN 是这里的瓶颈(如果我错了请纠正我)? 但我确实知道该查询正在做正确的事情,因为我已经尝试过滤一天(而不是一周)。
我的问题是如何加快这个查询。我已经考虑过添加这样的索引:
CREATE INDEX table_2_index ON table_2(customer_id, timestamp)
但是这个查询也需要很长时间。
有什么建议吗?
【问题讨论】:
-
如果
EXPLAIN ANALYZE花费的时间太长,您可以使用简单的EXPLAIN代替,它的用处要小得多,但它仍然可以显示数据库的想法。之后您可以手动验证步骤(即SELECT COUNT(*) FROM table WHERE ...) -
正如下面的答案中提到的,最终“加入然后聚合”可能会比“聚合然后加入”模式慢。在您的情况下,表
public.table_2应该是“主”,因此首先您应该优化select customer_id, sum(receipt) from table_2 where timestamp > '2019-03-25 00:00:00' and timestamp < '2019-04-01 00:00:00' group by customer_id之类的查询,然后将其与table_1连接起来(我相信customer_id与@987654333 对具有相同的唯一性@)
标签: sql postgresql performance join indexing