目标
我想对可路由图中的每对顶点运行pgr_dijkstra
。我有一个简单的脚本,它获取每对顶点并对数据库启动pgr_dijkstra
。
使用PostgreSQL parallel query功能来加速它会很好。
我想实现一个“容易”的速度,而不需要实现先进的代码,如收缩。
问题
虽然我可以看到,对于我的一些表,explain analyze
显示了一个涉及Gather
和Parallel Seq Scan
的计划,但尝试在启用“并行”参数和PARALLEL SAFE
关键字的情况下运行pgr_dijkstra
实际上会使它变慢。
输入数据
我有一个支持PostGIS的数据库,其中包含一些使用osm2pgsql
导入的OSM
数据:
| 数据类型|尺寸|
| --------------|--------------|
| 节点(顶点)表|730个顶点|
| 节点(顶点)表|160 kB|
| 边表|1100个顶点|
| 边表|656 kB|
PostgreSQL及系统配置
CPU:第11代Intel Core i7- 1165 G7
| PostgreSQL参数|价值|
| --------------|--------------|
| min_parallel_table_scan_size
| 8kB|
| force_parallel_mode
|关闭|
| parallel_setup_cost
| 10个|
| parallel_tuple_cost
|零点零一|
| max_parallel_workers_per_gather
|八|
| max_parallel_workers
|八|
| max_worker_processes
|八|
我已经按照this recommendation将force_parallel_mode
设置为off
,但即使on
也没有任何区别。
将parallel_tuple_cost
从默认值更改为0.001
does not seem to help。
查询和结果
我设置了一个非常简单的pgr_dijkstra
调用,有SAFE
和没有SAFE
,源/目标顶点的id
是硬编码的:
CREATE OR REPLACE
FUNCTION pgr_parallel()
RETURNS VOID
AS $$
BEGIN
PERFORM pgr_dijkstra(
'
SELECT gid AS id,
source,
target,
length_m AS cost
FROM edges_table
WHERE
NOT source IS NULL
AND
NOT target IS NULL
AND
NOT the_geom IS NULL
AND NOT length_m IS NULL
',
ARRAY[161]
,
ARRAY[639]
,
directed := false
);
END;
$$ LANGUAGE 'plpgsql'
PARALLEL SAFE;
我有一个简单的脚本,它调用这个函数N次,它似乎并没有以并行的方式运行:
| 功能类型|顶点对的数量(N)|执行时间|
| --------------|--------------|--------------|
| undefined(非平行)|五万|67秒|
| PARALLEL SAFE
|五万|89秒|
作为一个额外的观察,我运行htop
,并看到在开始时,当(并行)脚本运行时,所有8个物理核心都被使用。但是当脚本完成向数据库发送“任务”时,htop
显示postgres
进程只使用了一个核心。
常见问题
如果我理解正确的话,如果有一些重要的independent work to be done by each worker,查询可以被“并行化”。在pgr_dijkstra
和任何其他最短路径查找算法的情况下,情况不是这样吗?我假设pgr_dijkstra
获取顶点和边,然后对它们运行独立的计算。
是否可以使用PostgreSQL
的parallel query
功能,使pgr_dijkstra
的至少一部分并行运行?如果是,如何进行?
- 注:* 在Crunchy Data和Paul Ramsey的this post中,
PARALLEL SAFE
用于包含pgr_dijkstra
的函数,但没有详细说明它是否运行得更快。
1条答案
按热度按时间mwngjboj1#
运行
\df+ pgr_dijkstra;
,我们看到函数是parallel unsafe
,所以不能在单个查询中并行化它。但是,您可以尝试并行运行多个查询(即在不同的顶点对之间)。但要注意的是,他们将争夺同样的资源。