我试图将巴西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
答案 0 :(得分:4)
答案 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。
我发现最快的解决方案是:
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;
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,仅使用索引中的空间变量)进行比较,这似乎是最便宜(最有效)的选项。