我在Amazon RDS db.r3.4xlarge实例上运行Postgres 9.4.4 - 16CPU,122GB内存。 我最近遇到了一个需要在大型表上进行相当直接聚合的查询(约2.7亿条记录)。查询需要5个多小时才能执行。
大表上的连接列和分组列已定义索引。我尝试将 work_mem 和 temp_buffers 设置为 1GB ,但它有很多帮助。
这是查询和执行计划。任何线索都将受到高度赞赏。
explain SELECT
largetable.column_group,
MAX(largetable.event_captured_dt) AS last_open_date,
.....
FROM largetable
LEFT JOIN smalltable
ON smalltable.column_b = largetable.column_a
WHERE largetable.column_group IS NOT NULL
GROUP BY largetable.column_group
这是执行计划 -
GroupAggregate (cost=699299968.28..954348399.96 rows=685311 width=38)
Group Key: largetable.column_group
-> Sort (cost=699299968.28..707801354.23 rows=3400554381 width=38)
Sort Key: largetable.column_group
-> Merge Left Join (cost=25512.78..67955201.22 rows=3400554381 width=38)
Merge Cond: (largetable.column_a = smalltable.column_b)
-> Index Scan using xcrmstg_largetable_launch_id on largetable (cost=0.57..16241746.24 rows=271850823 width=34)
Filter: (column_a IS NOT NULL)
-> Sort (cost=25512.21..26127.21 rows=246000 width=4)
Sort Key: smalltable.column_b
-> Seq Scan on smalltable (cost=0.00..3485.00 rows=246000 width=4)
答案 0 :(得分:1)
您说大型表上的加入密钥和分组键已编制索引,但您没有在小型表上提及加入密钥。
合并和排序是缓慢的重要原因。但是,我也担心你要返回~70万行数据。这对你真的有用吗?你需要返回那么多数据的情况是什么,但等待5个小时太长了?如果您不需要所有这些数据,那么尽可能早地进行过滤将是您实现的最大速度增益。