【问题标题】:Spatial Join Query Optimization on Large Data Set大数据集上的空间连接查询优化
【发布时间】:2013-04-04 07:24:51
【问题描述】:

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

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)

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

【问题讨论】:

  • 抱歉,我编辑了空格。我不喜欢水平滚动。
  • 如果 A.tilename = B.tilename 显然是连接逻辑的一部分,为什么不在连接子句中包含它?
  • @JakubKania 所以你的意思是 JOIN spatial_table_b B ON ST_Intersects(A.polygon, B.polygon) AND A.tilename = B.tilename ?查询计划没有变化。

标签: postgresql join query-optimization postgis greenplum


【解决方案1】:

怎么样:

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 上的两个表,然后才检查两个多边形是否相交。这将为您提供不同的查询计划,但我不确定它是否是您正在寻找的查询计划。

【讨论】:

  • 非常感谢@JakubKania。这更接近我想做的事情。唯一的问题是数据库在内部子查询之后将所有记录收集到一个节点。如果能在gather操作之前应用交集过滤就完美了。
  • @ablimit 我怀疑这是可能的。我能想到的唯一另一种方法是创建一个相关子查询,它将使用 GiST 索引进行搜索,但它将为每一行调用,因此您必须测量搜索与一个预定义多边形相交的多边形需要多少时间并进行比较与当前时间。此外,结果表明存在用于 int (postgresql.org/docs/9.2/static/btree-gist.html) 的 GIST,因此 (tilename,polygon) 上的索引值得一看。
猜你喜欢
  • 2018-03-07
  • 1970-01-01
  • 1970-01-01
  • 2012-08-01
  • 2017-06-24
  • 1970-01-01
  • 2022-01-18
  • 1970-01-01
  • 2015-06-27
相关资源
最近更新 更多