postgresql - 大数据集的空间连接查询优化

标签 postgresql join query-optimization postgis greenplum

我有一个用例,其中两组数据与昂贵的空间谓词连接在一起。为了并行化查询,我将空间宇宙划分为瓦片(以数千个为单位),这样只有属于同一瓦片的记录才需要使用空间谓词进行测试。查询如下:

SELECT ST_Area(ST_Intersection(A.polygon, B.polygon))
    / ST_Area(ST_Union( A.polygon, B.polygon))  AS a_ratio
FROM spatial_table_a A
JOIN spatial_table_b B ON ST_Intersects(A.polygon, B.polygon)
WHERE A.tilename = B.tilename;

理想情况下,查询计划应根据 tilename 散列记录,然后使用索引扫描连接或嵌套循环连接执行空间谓词检查 ST_Intersects

但是,我现在得到的是一个过早执行空间连接的次优计划。方案如下图:

->  Hash Join  (cost=759468.44..377874772.26 rows=2610 width=18)
         Hash Cond: "outer"."?column4?" = "inner"."?column4?"
             Join Filter: a.polygon && b.polygon AND _st_intersects(a.polygon, b.polygon)
             ->  Seq Scan on spatial_table_b b  (cost=0.00..409556.95 rows=288816 width=1034)
             ->  Hash  (cost=375827.86..375827.86 rows=283522 width=946)
                   ->  Seq Scan on spatial_table_a a  (cost=0.00..375827.86 rows=283522 width=946)

所以,我的问题是:如何强制查询优化器生成更好的计划(这基本上改变了连接顺序)?

最佳答案

怎么样:

SELECT ST_Area(ST_Intersection(a, b))
    / ST_Area(ST_Union( a, b))  AS a_ratio
FROM
(
 SELECT a.polygon AS a, b.polygon AS b
 FROM  spatial_table_a A
 JOIN spatial_table_b B 
   ON A.tilename = B.tilename
 OFFSET 0
) AS q
WHERE ST_Intersects(a, b);

这应该会强制查询规划器首先连接 tilename 上的两个表,然后才检查两个多边形是否相交。这会给你一个不同的查询计划,但我不确定它是否是你正在寻找的查询计划。

关于postgresql - 大数据集的空间连接查询优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15959977/

相关文章:

python - 如何使用 SQLAlchemy 连接到 Amazon Redshift 中的集群?

mysql - 如何使用 2 个值在 2 个表之间进行连接?

php - 连接 2 个其他表和 2 个连接表中的条件

mysql - 通过表连接优化慢速 Lon/Lat 查询

hadoop - 如何编写查询以避免在选择不同和大小的 collect_set 配置单元查询中使用单个 reducer?

ruby-on-rails - PG::UndefinedColumn:如果同一数据库用于在 Rails 中相互连接的两个不同项目,则出现错误

sql - 为什么postgresql在这个查询中不使用索引

windows - Windows 上的 pg_upgrade 无法写入日志文件 pg_upgrade_internal.log

mysql - SQL 连接或相同的 id

mysql - MySQL如何使用多字段索引进行中间索引字段为OR的查询?