优化大型ST_Intersect查询,将1.8m OSM街道与317k多边形相匹配

时间:2015-10-02 12:44:53

标签: postgresql postgis

我试图将巴西Open Street Maps(OSM)的所有街道空间与Postgis中的2010年Census Enumeration区形状文件进行匹配。

我使用WGS84投影将所有文件导入Postgis并包含空间索引(要点)。

OSM数据来自geofabrik planet_osm_line,我过滤它只提取街道。有180万条街道。

Enumeration区shapefile有31.7万个多边形。 shapefile不是太精确,所以理想情况下我会在它们周围添加一个缓冲区来确保。

直接在街道上的ST_Intersects到枚举区一直在采取行动。因此,为了减少空间匹配的数量,首先将OSM街道与市政多边形连接起来,创建OSM_Streets_by_Mun表。巴西有5560个城市,而Enumeration区则嵌套在其中。

因此,最后的查询,包括州和市政代码的数字匹配,以减少仅在市政当局内的空间匹配。

尽管如此,即使在5天之后,查询仍未完成4核128GB的RAM服务器。

关于如何改善表现的任何想法?

25 B

以下是查询

上EXPLAIN命令的输出
CREATE TABLE OSM_Streets_by_SetorCensitario AS
SELECT OSM_Streets_by_Mun.*, setor_censitarioL.geom
FROM OSM_Streets_by_Mun, setor_censitarioL
WHERE   OSM_Streets_by_Mun.cod_UF = substring(setor_censitarioL.cd_geocodi,1,2) AND
        OSM_Streets_by_Mun.cod_mun = substring(setor_censitarioL.cd_geocodi,1,7) AND
        ST_Intersects(way,ST_Buffer(setor_censitarioL.geom,0.005))=true

3 个答案:

答案 0 :(得分:4)

  1. 从查询中删除文本匹配 - 空间就好了,否则它不会使用空间索引,只是在两个表上顺序迭代;
  2. 在表格中预先计算您的ST_Buffer;
  3. 向表中添加空间索引并使用它对表进行CLUSTER;
  4. 对于布尔函数,不要写= true,它们本身就足够了。

答案 1 :(得分:2)

几何体上WHERE中使用的任何(大多数)函数都会导致您的索引不会被计划。当然,您可以重新计算所有值或添加一些列(如ST_Buffer(geom,0.005)并在其上创建索引。如果您不想触摸表并需要使用函数,请在索引中使用它 - < / p>

Create index table_geom_buffer_idx on table using gist(st_buffer(geom,0.005));

应该这样做。

答案 2 :(得分:0)

OP在这里。根据其他问题的建议(tks!),我进行了一些不同规格的测试。 It is all docummented in this code, along with EXPLAIN output and run time for each query

我发现最快的解决方案是:

  • 根据市政代码和空间变量以及该指数的CLUSTERING创建索引

CREATE INDEX setor_censitarioL_index3 ON setor_censitarioL USING gist (cod_mun,geom); CLUSTER setor_censitarioL using setor_censitarioL_index3; CREATE INDEX OSM_Streets_by_Mun_index3 ON OSM_Streets_by_Mun USING gist (cod_mun,way); CLUSTER OSM_Streets_by_Mun using OSM_Streets_by_Mun_index3;

  • ST_DWithin()而不是预先计算缓冲区。

CREATE TABLE OSM_Streets_by_SetorCensitario AS SELECT osm_id, cd_geocodi as cod_setor FROM OSM_Streets_by_mun INNER JOIN setor_censitarioL ON OSM_Streets_by_mun.cod_mun=setor_censitarioL.cod_mun AND ST_DWithin(way,geom,0.005);**strong text**

这可以在1小时36分钟内完成工作(4核,128GB RAM服务器)。我将该查询的EXPLAIN的结果与其他选项(使用缓冲区预编译geom,仅使用索引中的空间变量)进行比较,这似乎是最便宜(最有效)的选项。