我在通过osm2pgrouting创建的postgis数据库上使用pgrouting。它在有限的数据集(3.5k种方式,所有最短路径A *搜索<20 ms)上表现非常好。

但是,由于我从Europe.osm导入了一个更大的边界框(122k种方式),性能下降很多(最短路径花费约900ms)。

我认为使用A *不会使这些边缘中的大多数边缘被遮挡。

到目前为止,我为改善性能所做的工作速度:


在几何列上添加索引(无明显影响)
将我的内存从8GB增加到16GB
更改postgresql内存设置(shared_buffers, Effective_cache_size)从(128MB,128MB)到(1GB,2GB)(无明显效果)

我感觉大部分工作都在制作图形的C Boost库中完成所以优化postgresql不会给我更好的结果。当我对每次搜索选择的A *行集进行细微更改时,我有点担心boost库无法缓存我的图,并且每次都必须重建所有122k边(即使它只会使用非常每个查询的子集有限)。而且我不知道与实际的最短路径搜索相比,花了多少钱。

你们中的任何人是否在122k或更大的OSM数据集上使用pgrouting?我应该期待什么表现?哪些设置对性能的影响最大?

评论

我不是专家,但是您可以缓存结果吗,例如,如果您知道始终使用公共子路由,则可以对其进行预缓存吗?因此,您必须减少搜索量?另外,您将搜寻范围限制在动脉和收藏家吗?

我允许免费搜索atm,所以我不认为我可以为子路线承担很多责任。另外,我正在缓存最近x分钟的搜索结果,但这对我的新搜索没有帮助。我有一个感觉,只要我可以将整个图形保持在内存中,此尺寸上的A *应该仍然非常快。必须有在整个国家/地区使用这种方法的人,他们知道如何提高性能。

另一种选择是建立一个O / D矩阵(起点/终点矩阵)。这是我们在流量工程中使用的技术。将网络分成多个区域,因此,假设一个大城市可能有100个区域。每个区域将具有一个虚拟质心。通过虚拟链接将质心连接到网络。然后,您可以将整个网络重塑为100 x 100次行程(总共10,000次行程)。当用户进行搜索时,灌浆必须在始发端和目标端找到一条靠近质心或虚拟链接的路径。

如果有人想从一个区域转到下一个区域,但他们却通过质心被路由,您不会得到奇怪的结果吗?还是仅在区域分开时才使用此功能?如果客户想要从A到B最快,那么您的解决方案最有意义,但是在我的情况下,我不得不与那些想要散步,骑自行车等以休闲,想选择独特路线而不被迫走的客户打交道通过标准路线。

如果您正在寻找一种多式联运解决方案(自行车,步行,公共交通,驾车),则应该看看俄勒冈州波特兰市的TriMet多式联运选址站点,该站点使用OpenTripPlanner:trimet.org/news/releases/oct15-rtp。 htm

#1 楼

当面对这样的任务时,您的主要目标是保持理性。不要基于“胆量感觉”改变参数。虽然直觉似乎对好莱坞有效,但不适用于生活在现实世界中的我们。好吧,至少不是我的直觉;-)。

您应该:


建立一个可用且可重复的度量标准(例如灌浆查询所需的时间)
将指标结果保存到电子表格中并取平均值(最好和最差)。这将告诉您您所做的更改是否朝着正确的方向
在查询运行时使用top和vmstat监视服务器(假设您使用的是* nix),并查找有效的模式:大量io,高CPU,交换等。如果CPU正在等待I / O,请尝试提高磁盘性能(这应该很容易,请参见下文)。如果CPU的100%占用大量磁盘空间,则必须找到一种改进查询的方法(这可能会更困难)。

为简单起见,我假设网络是在这里起不到重要作用。

提高数据库性能

升级到最新的Postgres版本。版本9比以前的版本好得多。它是免费的,所以您没有理由不用。

在这里阅读我已经推荐的书。

您应该真正阅读它。我相信与此案有关的章节是5,6,10,11

提高磁盘性能


获取SSD驱动器并将整个数据库放在上面。读取性能很可能会翻两番,写入性能也应该从根本上改善。
为postgres分配更多的内存。理想情况下,您应该能够分配足够的内存,以便可以将整个(或最热的部分)缓存到内存中,但又不要缓存太多,以免发生交换。交换非常不好。在上一段落中引用的书中对此进行了介绍
在所有磁盘上禁用atime(将noatime选项添加到fstab)

提高查询性能

使用上面引用的书中描述的工具来跟踪您的查询并查找值得优化的站点。

更新

评论后,我看了看源代码对于存储过程

https://github.com/pgRouting/pgrouting/blob/master/core/src/astar.c

,似乎一旦查询由于该算法完全在内存中运行(并且不幸的是仅在一个cpu上运行),因此没有太多改进的余地。恐怕您唯一的解决方案是找到一种更好/更快的算法,或者一种可以运行多线程的算法,然后通过创建诸如pgrouting之类的库或使用某种中间件来检索数据(并可能对其进行缓存)将其与postgres集成,并且将其输入算法。

HTH

评论


我已经阅读了您推荐的书的一部分。我的数据集仍然很小,无法完全容纳到内存中,因此我认为磁盘性能不应成为瓶颈(我会在测试时更好地检查我的资源以确认这一点)。我认为Postgresql仅在进行简单的select * from table来向C Boost库提供行/元组以执行真正的搜索时才在灌浆过程中起作用((有人可以确认这一点),所以我担心没有您对Postgresql的性能似乎很好,但对于提高特定性能却可能并非如此。

–mrg
2011-11-15 14:02

@mrg我实际上已经想到了这一点,但是我想确保您没有遗漏那些低落的果实。考虑到这一点,您从3.5ms的20ms变为122k的900ms,这并不完美。祝好运

– Unicoletti
2011-11-15 14:24

固态硬盘确实可以提高性能(与高速缓存的速度类似)

– Mapperz♦
2011年11月15日14:57



以我的经验,如果对所有数据集(表)使用pgrouting,那么Postgres引擎并不会带来太大的好处。索引甚至没有使用,因此它毫无用处。在每个查询中,整个表都被加载到内存中。共享缓冲区和缓存也没有带来任何性能优势,因为每个查询都将所有表加载到内存中。如果有人成功重用了内存中加载的数据用于后续查询,请告诉我们。我在SDD驱动器中只能看到可能的性能提高,但是我从未测试过。更多的内存仅允许更多的并发查询,而不是性能。

–马里奥·米尔勒(Mario Miler)
2011年11月15日在16:27



#2 楼

我有同样的问题,正要在邮件列表中询问,所以谢谢大家!

我在路由表上使用百万行半的射击之星。计算大约需要十秒钟。对于2万行,将花费近三秒钟。我需要流星,因为我需要转弯限制。

以下是我要实现的一些想法:



在SQL上, pgRouting得到了使用st_buffer的方法,所以它并没有得到所有方法,而只是“附近”的方法:

select * from shortest_path_shooting_star(
'SELECT rout。* FROM routing rout ,
(从st_buffer(st_envelope(st_collect(ge_collect(geometry)),4)中选择几何
),其中id ='|| source_ ||或id ='|| target ||')e
where rout.geometry && e.geometry',
source,target,true,true);


它提高了性能,但是如果需要的话在缓冲区之外,它可以返回“找不到路径”错误,所以...大缓冲区?多次调用增加缓冲区直到找到方法?


快速路由已缓存

像dassouki建议的那样,我将缓存一些“有用的”路由,因此如果距离太长了,它可以通过这些快速路径,而只需要找到进出它们的方式即可。




gis索引的分区表

但是我想,如果它涉及到内存,那并不重要...无论如何都应该对其进行测试。

,如果您发现其他想法,请继续发布。

另外,您是否知道Postgres9是否有一些已编译的pgRouting?

评论


+1这里似乎有一些有用和建设性的想法。请注意,如果您希望回答问题,那么最好将其表述为新问题。我们的常见问题解答将告诉您如何进行。

– hu
2011年11月16日14:59

Délawen,我也一直在考虑您的第一个想法(ST_Buffer),并预见到同样的问题。但是,优点可能有两种:数据集较小,因此速度更快,并且随着更多的处理在Postgresql中完成,您将有再次优化它的方法。 Atm我正在使用Ubuntu 11,其中PostgreSQL 8.4是最新版本。

–mrg
2011年11月16日15:42



MRG,我在Ubuntu Maverick上为PostgreSQL 9.0编译了pgRouting,没有太大问题。 PostgreSQL 9.0的Postgis可以在这里找到:ppa.launchpad.net/pi-deb/gis/ubuntu maverick / main amd64软件包

–德拉文
2011年11月16日17:10



我提出了两个想法。 1)“快速路由已缓存”和“ st_buffer”的组合。这样一来,您可以保证找到一条路线,而不会有人被迫走上同一条路线。 2)仅使用postgis填充静态图形(使用Boost(C),nx_spatial(Python),neo4j(Java)等),并将该图形用于每个搜索查询。

–mrg
2011年11月16日17:49



当起点和终点之间的距离大于阈值时,如何降低“快速”边缘(如高速公路)的成本(即提高优先级)呢?提升因子也可能与距离有关:距离越长,距离越短。

– Unicoletti
2011年11月18日在8:48

#3 楼

我们刚刚在git中创建了一个分支,用于转弯受限的最短路径@
https://github.com/pgRouting/pgrouting/tree/trsp

对不起,尚无文档,但是如果您在pgRouting列表上问一些问题,我会在那里闲逛并会回复。该代码比流星运行的速度快得多,并且基于Dijkstra算法。

-Steve

#4 楼

我有一个包含〜1200000边的源路由表。在配备SSD的i7上,创建路由需要12秒钟。
我要提高性能的想法是将边缘表分成几个缩放级别表。我的意思是与Google瓷砖相同的水平。
在第8缩放水平上,我有88张桌子。每个表格包含一条道路的子集,它们的区域彼此重叠,以便计算彼此之间相距不超过290 km的两个点之间的路线需要2秒钟。
在第9层计算时,其计算时间降至0.25秒钟,我们就拥有352个表格。
在编辑道路的情况下,所有图形的重建都不会超过一个小时。
提高路由速度的根本方法是使用Floyd-Warshall算法。但是没有人知道在如此多的边缘上计算前身矩阵需要多少费用。