PostgreSQL聪明地使用ST_Within

时间:2013-06-13 12:27:50

标签: postgresql postgresql-9.2

也许我的问题看起来很愚蠢,但我想问一下有人可以告诉我如何改进这个问题:

UPDATE twitter
   SET poi=poi.type_name FROM poi
 WHERE ST_Within (ST_SetSRID(ST_MakePoint(x_coords,y_coords),4326),
 ST_SetSRID(ST_Buffer(poi.wkb_geometry, 0.0005),4326));

我有2个包含点的表:“twitter”和“poi”,我需要在“poi”周围创建一个50米的缓冲区找到此缓冲区内的所有“twitter”点,然后将“type_name”属性“poi”复制到“twitter”点。 问题是查询持续时间太长,似乎永远不会完成,我不时会尝试检查某些属性是否被复制,但“twitter.poi”列始终为空。

我尝试通过添加 WHERE“username来限制查询,以检查查询是否正确且有效。

UPDATE twitter
       SET poi=poi.type_name FROM poi
     WHERE uname='some_username' AND ST_Within (ST_SetSRID(ST_MakePoint(x_coords,y_coords),4326),
     ST_SetSRID(ST_Buffer(poi.wkb_geometry, 0.0005),4326));

我唯一无法理解的是如何改进整个“twitter”表的查询。

1 个答案:

答案 0 :(得分:2)

您没有提供表格定义,但表格twitter中的坐标似乎有两列:x_coordsy_coords。用geometry列替换那些并创建一个简单的GiST索引或创建一个函数GiST索引,如:

CREATE INDEX idx_twitter_point_4326
ON twitter  USING gist (ST_SetSRID(ST_MakePoint(x_coords,y_coords), 4326));

poi上的另一个:

CREATE INDEX idx_poi_wkb_geometry_4326
ON poi USING gist (ST_SetSRID(p.wkb_geometry, 4326));

这应该用于加快ST_Within()

  

此函数调用将自动包含一个边界框   比较将使用几何上可用的任何索引。

功能ST_distance()可能会为您提供更好的服务:

UPDATE twitter t
SET    poi = p.type_name
FROM   poi p
WHERE  ST_Distance(ST_SetSRID(ST_MakePoint(t.x_coords, t.y_coords), 4326)
                  ,ST_SetSRID(p.wkb_geometry, 4326)) < 0.0005
AND    t.poi IS DISTINCT FROM p.type_name;

这假设在poi条目附近最多只能有一个 twitter。否则,您应该使用一个子查询,为每个poi选择最接近的 twitter

额外的WHERE子句t.poi IS DISTINCT FROM p.type_name可以避免空更新。

我自己没有使用PostGis,所以未经测试。