Estoy usando pgrouting en una base de datos postgis creada a través de osm2pgrouting. Funciona muy bien en un conjunto de datos limitado (3.5k formas, todas las rutas A * más cortas buscan <20 ms).
Sin embargo, desde que importé un cuadro delimitador más grande (122k formas) desde europe.osm, el rendimiento bajó mucho (un camino más corto cuesta alrededor de 900ms).
Creo que usar A * la mayoría de esos bordes nunca serán visitados ya que están fuera del camino.
Lo que he hecho hasta ahora en un intento de mejorar la velocidad:
- Poner un índice en la columna de geometría (sin efecto notable)
- Aumenté mi memoria de 8GB a 16GB
- Cambie la configuración de memoria postgresql (shared_buffers, efectivo_caché_tamaño) de (128MB, 128MB) a (1GB, 2GB) (sin efecto notable)
Tengo la sensación de que la mayor parte del trabajo se está realizando en la biblioteca C Boost donde se está haciendo el gráfico, por lo que optimizar postgresql no me dará resultados mucho mejores. A medida que hago pequeños cambios en el conjunto de filas que selecciono para A * para cada búsqueda, tengo un poco de miedo de que la biblioteca de impulso no pueda almacenar en caché mi gráfico y tenga que reconstruir todos los 122k bordes cada vez (aunque solo usará un muy subconjunto limitado de cada consulta). Y no tengo idea de cuánto se gasta haciendo eso en comparación con la búsqueda de ruta más corta real.
¿Alguno de ustedes usa pgrouting en un conjunto de datos OSM de 122k o más? ¿Qué rendimiento debo esperar? ¿Qué ajustes afectan más el rendimiento?
Respuestas:
Cuando te enfrentas a tareas como esta, tu objetivo principal es ser racional. No cambie los parámetros basados en el "presentimiento". Si bien el intestino parece funcionar para Hollywood, no lo es para nosotros que vivimos en el mundo real. Bueno, al menos no mi instinto ;-).
Debieras:
establecer una métrica utilizable y repetible (como el tiempo requerido por una consulta de pgrouting)
guardar los resultados de las métricas en una hoja de cálculo y promediarlos (descartar lo mejor y lo peor). Esto le dirá si los cambios que está haciendo van en la dirección correcta
supervise su servidor usando top y vmstat (suponiendo que esté en * nix) mientras se ejecutan las consultas y busque patrones significativos: mucha io, CPU alta, intercambio, etc. Si la CPU está esperando E / S, intente mejorar rendimiento del disco (esto debería ser fácil, ver más abajo). Si, en cambio, la CPU está al 100% sin ninguna actividad de disco significativa, debe encontrar una manera de mejorar la consulta (esto probablemente será más difícil).
En aras de la simplicidad, supongo que la red no está desempeñando ningún papel importante aquí.
Mejora del rendimiento de la base de datos.
Actualice a la última versión de Postgres. La versión 9 es mucho mejor que las versiones anteriores. Es gratis, así que no tienes razón para no hacerlo.
Lea el libro que recomendé ya aquí .
Realmente deberías leerlo. Creo que los capítulos relevantes para este caso son 5,6,10,11
Mejora del rendimiento del disco
Obtenga una unidad SSD y coloque toda la base de datos en ella. El rendimiento de lectura probablemente se cuadruplicará y el rendimiento de escritura también debería mejorar radicalmente
asignar más memoria a postgres. Idealmente, debería poder asignar suficiente memoria para que la totalidad (o la parte más activa) pueda almacenarse en la memoria caché, pero no demasiado para que se produzca el intercambio. El intercambio es muy malo. Esto está cubierto en el libro citado en el párrafo anterior.
deshabilite atime en todos los discos (agregue las opciones de noatime a fstab)
Mejora del rendimiento de la consulta
Use las herramientas descritas en el libro citado anteriormente para rastrear sus consultas y encontrar paradas que valga la pena optimizar.
Actualizar
Después de los comentarios, he mirado el código fuente del procedimiento almacenado
https://github.com/pgRouting/pgrouting/blob/master/core/src/astar.c
y parece que una vez que la consulta se ha ajustado, no hay mucho más margen de mejora ya que el algoritmo se ejecuta completamente en la memoria (y, desafortunadamente, solo en una CPU). Me temo que su única solución es encontrar un algoritmo mejor / más rápido o uno que pueda ejecutar multiproceso y luego integrarlo con postgres, ya sea creando una biblioteca como pgrouting o usando algún middleware para recuperar los datos (y almacenarlos en caché, tal vez) y alimentarlo al algoritmo.
HTH
fuente
Tengo el mismo problema y estaba a punto de preguntar en las listas de correo, ¡así que gracias a todos!
Estoy usando Shooting Star con un millón y medio de filas en la tabla de enrutamiento. Se tarda casi diez segundos en calcularlo. Con 20k filas, lleva casi tres segundos. Necesito Shooting Star porque necesito las restricciones de giro.
Aquí hay algunas ideas que estoy tratando de implementar:
En el SQL donde pgRouting obtiene las formas, use un st_buffer para que no obtenga todas las formas, sino solo las formas "cercanas":
seleccione * de shortest_path_shooting_star ('SELECCIONAR ruta. * DESDE ruta de ruta, (seleccione st_buffer (st_envelope (st_collect (geometry)), 4) como geometría de ruta donde id =' || source_ || 'or id =' || target | | ') e DONDE rout.geometry && e.geometry', fuente, destino, verdadero, verdadero);
Mejoró el rendimiento, pero si el camino necesita salir del búfer, puede devolver un error de "no se encontró ruta", entonces ... ¿gran búfer? varias llamadas aumentando el búfer hasta que encuentre un camino?
Como sugirió dassouki, guardaré en caché algunas rutas "útiles" para que, si la distancia es demasiado larga, pueda atravesar estas rutas rápidas y solo tenga que encontrar la forma de entrar y salir de ellas.
Pero supongo que, si va a la memoria, realmente no importa ... Debería probarlo, de todos modos.
Por favor, sigue publicando si encuentras otra idea.
Además, ¿sabe si hay algún pgRouting compilado para Postgres9?
fuente
Acabamos de crear una rama en git para una ruta más corta restringida a su vez @ https://github.com/pgRouting/pgrouting/tree/trsp
Lo siento, todavía no hay documentación, pero si haces preguntas en la lista de pgRouting, salgo y responderé. Este código se ejecuta mucho más rápido que la estrella fugaz y se basa en el algoritmo Dijkstra.
-Steve
fuente
Tengo una tabla de ruta de origen que contiene ~ 1200000 bordes. En mi i7 con SSD, se necesitan 12 segundos para crear una ruta. Mi idea para aumentar el rendimiento es dividir la tabla de borde en varias tablas de nivel de zoom. Me refiero al nivel que es idéntico al de google tiles. En el octavo nivel de zoom, por ejemplo, tengo 88 tablas. Cada tabla contiene un subconjunto de carreteras y sus áreas se superponen entre sí para calcular una ruta entre dos puntos que se encuentran a una distancia no mayor de 290 km. En el noveno nivel, el tiempo de cálculo cae a 0.25 segundos y tenemos 352 tablas. La recreación de todos los gráficos en caso de que editemos carreteras no lleva más de una hora. La forma radical de aumentar la velocidad de enrutamiento es utilizar el algoritmo Floyd-Warshall. Pero nadie sabe cuánto se tarda en calcular la matriz predecesora en tantos bordes.
fuente