Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance PostgreSQL/PostGIS中检查100万行字符串是否相互交叉的最有效方法?_Performance_Postgresql_Postgis - Fatal编程技术网

Performance PostgreSQL/PostGIS中检查100万行字符串是否相互交叉的最有效方法?

Performance PostgreSQL/PostGIS中检查100万行字符串是否相互交叉的最有效方法?,performance,postgresql,postgis,Performance,Postgresql,Postgis,我在表格的几何体字段“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

我在表格的几何体字段“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_Shortest Line在400000个地块和40000条道路线串之间生成的“线”表。我已经删除了穿过道路或地块的线。该表包含来自原始地块及其终点道路的唯一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       
;

编辑3:使用ST_相交而不是ST_交叉将运行时间缩短到343616毫秒。

使用ST_DWithin您只能与您身边的人进行比较。并将使用索引。我的桌子是500k排,花了大约30秒

这是我的示例,当一个节点与道路网络断开连接时,我比较结束/开始节点,并检查是否与另一个结束/开始节点相交

因此,仅与接近1米的一个进行比较。而不是与自己相比

我认为值
0.0001
取决于您的项目,但使用
ST_Distance
很容易测试

SELECT 
      f.id as node_id, 
      g.id as line_id,
      'start_node' as type
FROM ways_rto f 
JOIN ways_rto g
  on ST_DWithin(f.sp, g.geom, 0.0001)
 and ST_Intersects(f.sp, g.geom)
 and NOT ( f.sp_txt = g.sp_txt OR f.sp_txt = g.ep_txt)
WHERE f.id <> g.id
选择
f、 id作为节点\ u id,
g、 id作为行\u id,
“启动节点”作为类型
从方法到方法
连接方式
在圣杜维辛(f.sp,g.geom,0.0001)
和ST_相交(f.sp,g.geom)
而不是(f.sp_txt=g.sp_txt或f.sp_txt=g.ep_txt)
其中f.id g.id
更新:我做了另一个重复数据的测试,时间是60秒。我所能看到的唯一区别是我将点与线进行比较

解释分析

"Nested Loop  (cost=0.00..10748875.97 rows=1083 width=8) (actual time=13913.424..60016.767 rows=136 loops=1)"
"  ->  Seq Scan on test_rto g  (cost=0.00..54344.94 rows=1379094 width=140) (actual time=0.298..196.095 rows=1379094 loops=1)"
"  ->  Index Scan using test_rto_sp_idx on test_rto f  (cost=0.00..7.74 rows=1 width=55) (actual time=0.041..0.041 rows=0 loops=1379094)"
"        Index Cond: ((sp && st_expand(g.geom, 0.0001::double precision)) AND (sp && g.geom))"
"        Filter: ((sp_txt <> g.sp_txt) AND (sp_txt <> g.ep_txt) AND (id <> g.id) AND (g.geom && st_expand(sp, 0.0001::double precision)) AND _st_dwithin(sp, g.geom, 0.0001::double precision) AND _st_intersects(sp, g.geom))"
"        Rows Removed by Filter: 7"
"Total runtime: 60016.872 ms"
“嵌套循环(成本=0.00..10748875.97行=1083宽度=8)(实际时间=13913.424..60016.767行=136个循环=1)”
“->测试时的顺序扫描(成本=0.00..54344.94行=1379094宽度=140)(实际时间=0.298..196.095行=1379094循环=1)”
“->使用test_rto_sp_idx对test_rto f进行索引扫描(成本=0.00..7.74行=1宽度=55)(实际时间=0.041..0.041行=0循环=1379094)”
“索引条件:((sp&st_展开(g.geom,0.0001::双精度))和(sp&g.geom))”
“过滤器:((sp_txt g.sp_txt)和(sp_txt g.ep_txt)和(id g.id)和(g.geom和&st_展开(sp,0.0001::双精度))和_st_dwithin(sp,g.geom,0.0001::双精度)和_st_相交(sp,g.geom))”
“由筛选器删除的行:7”
“总运行时间:60016.872毫秒”

谢谢胡安·卡洛斯(Juan Carlos),在1/3米的高度上,这确实缩短了几分钟,现在是30分钟,而以前是33分钟。你能分享一下
解释分析
吗?看来你还出了什么问题
1M^2=1E12
500k^2是2.5E11
所以应该只难10倍?你能试着做一个500k的小表格只是为了比较吗?我把数据的大小增加了一倍,只需要60秒,你有别的东西在减慢这个过程。正如你所看到的,索引完成了大部分工作,请看我在原始问题中添加的解释分析。是的,我正要提出这个建议。你能试试ST_Intersect吗?你能告诉我如何用索引定义你的表吗?
SELECT 
      f.id as node_id, 
      g.id as line_id,
      'start_node' as type
FROM ways_rto f 
JOIN ways_rto g
  on ST_DWithin(f.sp, g.geom, 0.0001)
 and ST_Intersects(f.sp, g.geom)
 and NOT ( f.sp_txt = g.sp_txt OR f.sp_txt = g.ep_txt)
WHERE f.id <> g.id
"Nested Loop  (cost=0.00..10748875.97 rows=1083 width=8) (actual time=13913.424..60016.767 rows=136 loops=1)"
"  ->  Seq Scan on test_rto g  (cost=0.00..54344.94 rows=1379094 width=140) (actual time=0.298..196.095 rows=1379094 loops=1)"
"  ->  Index Scan using test_rto_sp_idx on test_rto f  (cost=0.00..7.74 rows=1 width=55) (actual time=0.041..0.041 rows=0 loops=1379094)"
"        Index Cond: ((sp && st_expand(g.geom, 0.0001::double precision)) AND (sp && g.geom))"
"        Filter: ((sp_txt <> g.sp_txt) AND (sp_txt <> g.ep_txt) AND (id <> g.id) AND (g.geom && st_expand(sp, 0.0001::double precision)) AND _st_dwithin(sp, g.geom, 0.0001::double precision) AND _st_intersects(sp, g.geom))"
"        Rows Removed by Filter: 7"
"Total runtime: 60016.872 ms"