【发布时间】:2016-01-15 15:34:42
【问题描述】:
我在表格的几何字段“geom”中有一百万条线串。我试图找到相互交叉的线串,以便我可以从原始表中删除它们。 我在“geom”上创建了一个 GIST 空间索引,并将该表聚集在该索引上。有没有更有效的方法,不需要进行一万亿次 (10^6 x 10^6) 的比较?
SELECT (CASE WHEN A.length >= B.length THEN A.gid ELSE B.gid END)
INTO lines_self_crossing
FROM lines AS A, lines AS B
WHERE ST_Crosses(A.geom, B.geom) = true
;
我正在清理使用 ST_ShortestLine 在 400,000 个宗地和 40,000 个道路线串之间生成的“线”表。我已经删除了穿过道路或地块的线。该表包含来自原始宗地及其终点的道路的唯一 ID。
编辑 这是重写的查询,并解释分析输出:
explain analyze
SELECT (CASE WHEN A.length >= B.length THEN A.gid ELSE B.gid END)
INTO shortline_crosses_shortline2
FROM parcelstiug_roadciu1mwt_sl_noroadnoparcelcross AS A
JOIN parcelstiug_roadciu1mwt_sl_noroadnoparcelcross AS B
ON ST_DWithin(A.geom, B.geom, 1)
AND ST_Crosses(A.geom, B.geom) = true
WHERE A.gid <> B.gid
;
解释分析的输出:
` Nested Loop (cost=0.29..4273300.12 rows=96 width=24) (actual time=6.111..1692272.505 rows=8363188 loops=1)
-> Seq Scan on parcelstiug_roadciu1mwt_sl_noroadnoparcelcross a (cost=0.00..21795.31 rows=897431 width=76) (actual time=0.008..128.911 rows=897431 loops=1)
-> Index Scan using ptiugrciu1mwtslnrnpc_spindex on parcelstiug_roadciu1mwt_sl_noroadnoparcelcross b (cost=0.29..4.73 rows=1 width=76) (actual time=0.806..1.881 rows=9 loops=897431)
Index Cond: ((geom && st_expand(a.geom, 1::double precision)) AND (a.geom && geom))
Filter: ((a.gid <> gid) AND (a.geom && st_expand(geom, 1::double precision)) AND _st_dwithin(a.geom, geom, 1::double precision) AND _st_crosses(a.geom, geom))
Rows Removed by Filter: 74
Total runtime: 1696618.617 ms`
EDIT2 索引定义如下:
CREATE INDEX ptiugrciu1mwtslnrnpc_gid
ON parcelstiug_roadciu1mwt_sl_noroadnoparcelcross
USING btree
(gid);
CREATE INDEX ptiugrciu1mwtslnrnpc_parceltayoid
ON parcelstiug_roadciu1mwt_sl_noroadnoparcelcross
USING btree
(parcel_tayoid);
CREATE INDEX ptiugrciu1mwtslnrnpc_roadgid
ON parcelstiug_roadciu1mwt_sl_noroadnoparcelcross
USING btree
(road_gid);
CREATE INDEX ptiugrciu1mwtslnrnpc_spindex
ON parcelstiug_roadciu1mwt_sl_noroadnoparcelcross
USING gist
(geom);
ALTER TABLE parcelstiug_roadciu1mwt_sl_noroadnoparcelcross CLUSTER ON ptiugrciu1mwtslnrnpc_spindex;
EDIT3:使用 ST_Intersects 而不是 ST_Crosses 将运行时间缩短到 343616 毫秒。
【问题讨论】:
标签: performance postgresql postgis