J'utilise pgrouting sur une base de données postgis créée via osm2pgrouting. Il fonctionne très bien sur un ensemble de données limité (voies de 3,5 km, toutes les recherches A * du chemin le plus court <20 ms).
Cependant, depuis que j'ai importé une boîte englobante plus grande (122k voies) d'europe.osm, les performances ont beaucoup baissé (le chemin le plus court coûte environ 900 ms).
Je pense que l'utilisation de A * la plupart de ces bords ne seront jamais visités car ils sont à l'écart.
Ce que j'ai fait jusqu'à présent pour essayer d'améliorer la vitesse:
- Mettre un index sur la colonne de géométrie (pas d'effet notable)
- Augmentation de ma mémoire de 8 Go à 16 Go
- Modifiez les paramètres de mémoire postgresql (shared_buffers, effective_cache_size) de (128 Mo, 128 Mo) à (1 Go, 2 Go) (pas d'effet notable)
J'ai le sentiment que la plupart du travail se fait dans la bibliothèque C Boost où le graphique est fait, donc l'optimisation de postgresql ne me donnera pas de bien meilleurs résultats. Comme je fais des changements mineurs à l'ensemble de lignes que je sélectionne pour A * pour chaque recherche, j'ai un peu peur que la bibliothèque de boost ne puisse pas mettre en cache mon graphique et doive reconstruire tous les 122k bords à chaque fois (même si elle n'utilisera qu'une très sous-ensemble limité à chaque requête). Et je n'ai aucune idée du montant dépensé pour cela par rapport à la recherche du chemin le plus court.
L'un de vous utilise-t-il le pgroutage sur un ensemble de données OSM de 122k ou plus? À quelle performance dois-je m'attendre? Quels paramètres affectent le plus les performances?
Réponses:
Face à de telles tâches, votre objectif principal est d'être rationnel. Ne changez pas les paramètres en fonction du «sentiment d'intestin». Alors que l'intestin semble fonctionner pour Hollywood, il ne l'est pas pour nous qui vivons dans le monde réel. Eh bien, du moins pas mon instinct ;-).
Vous devriez:
établir une métrique utilisable et répétable (comme le temps requis par une requête de pgrouting)
enregistrez les résultats des mesures dans une feuille de calcul et faites-en la moyenne (jetez le meilleur et le pire). Cela vous dira si les changements que vous apportez vont dans la bonne direction
surveillez votre serveur en utilisant top et vmstat (en supposant que vous êtes sur * nix) pendant l'exécution des requêtes et recherchez des modèles significatifs: beaucoup d'io, CPU élevé, échange, etc. Si le CPU attend les E / S, essayez d'améliorer les performances du disque (cela devrait être facile, voir ci-dessous). Si le CPU est à 100% sans aucune acticité de disque significative, vous devez trouver un moyen d'améliorer la requête (cela va probablement être plus difficile).
Par souci de simplicité, je suppose que le réseau ne joue aucun rôle important ici.
Amélioration des performances de la base de données
Passez à la dernière version de Postgres. La version 9 est tellement meilleure que les versions précédentes. C'est gratuit donc vous n'avez aucune raison de ne pas le faire.
Lisez le livre que j'ai déjà recommandé ici .
Vous devriez vraiment le lire. Je crois que les chapitres pertinents pour cette affaire sont 5,6,10,11
Amélioration des performances du disque
Obtenez un disque SSD et mettez toute la base de données dessus. Les performances de lecture quadrupleront très probablement et les performances d'écriture devraient également s'améliorer radicalement
affecter plus de mémoire aux postgres. Idéalement, vous devriez être en mesure d'affecter suffisamment de mémoire pour que l'ensemble (ou la partie la plus chaude) puisse être mis en cache en mémoire, mais pas trop pour que l'échange se produise. L'échange est très mauvais. Ceci est couvert dans le livre cité au paragraphe précédent
désactiver atime sur tous les disques (ajouter les options noatime à fstab)
Amélioration de la performance des requêtes
Utilisez les outils décrits dans le livre cité ci-dessus pour tracer vos requêtes et trouver des arrêts qui méritent d'être optimisés.
Mise à jour
Après les commentaires, j'ai regardé le code source de la procédure stockée
https://github.com/pgRouting/pgrouting/blob/master/core/src/astar.c
et il semble qu'une fois la requête réglée, il n'y a pas beaucoup plus de place à l'amélioration car l'algorithme s'exécute complètement en mémoire (et, malheureusement, sur un seul processeur). Je crains que votre seule solution soit de trouver un algorithme meilleur / plus rapide ou capable de fonctionner en multithread puis de l'intégrer à postgres soit en créant une bibliothèque comme pgrouting ou en utilisant un middleware pour récupérer les données (et les mettre en cache, peut-être) et alimentez-le à l'algorithme.
HTH
la source
J'ai juste le même problème et j'allais demander sur les listes de diffusion, donc merci à tous!
J'utilise Shooting Star avec un million et demi de lignes sur la table de routage. Il faut près de dix secondes pour le calculer. Avec 20 000 lignes, cela prend près de trois secondes. J'ai besoin de Shooting Star parce que j'ai besoin des restrictions de virage.
Voici quelques idées que j'essaie de mettre en œuvre:
Sur le SQL où pgRouting obtient les chemins, utilisez un st_buffer pour qu'il n'obtienne pas tous les chemins, mais juste les chemins "voisins":
sélectionnez * dans shortest_path_shooting_star ('SELECT rout. * FROM rout rout, (sélectionnez st_buffer (st_envelope (st_collect (geometry)), 4) comme géométrie dans le routage où id =' || source_ || 'ou id =' || target | | ') e WHERE rout.geometry && e.geometry', source, cible, vrai, vrai);
Il a amélioré les performances, mais si le chemin doit aller en dehors du tampon, il peut renvoyer une erreur "aucun chemin trouvé", alors ... gros tampon? plusieurs appels augmentant le tampon jusqu'à ce qu'il trouve un moyen?
Comme l'a suggéré Dassouki, je vais mettre en cache certains itinéraires "utiles", donc si la distance est trop longue, il peut passer par ces itinéraires rapides et avoir juste à trouver le chemin pour entrer et sortir d'eux.
Mais je suppose que, si ça se remémore, ça n'a pas vraiment d'importance ... Faut le tester quand même.
Veuillez continuer à publier si vous trouvez une autre idée.
De plus, savez-vous s'il existe un pgRouting compilé pour Postgres9?
la source
Nous venons de créer une branche dans git pour un chemin le plus court limité en virage @ https://github.com/pgRouting/pgrouting/tree/trsp
Désolé, pas encore de documentation, mais si vous posez des questions sur la liste pgRouting, je traîne et je vous répondrai. Ce code fonctionne beaucoup plus rapidement que l'étoile filante et est basé sur l'algorithme de Dijkstra.
-Steve
la source
J'ai une table de routage source qui contient ~ 1200000 bords. Sur mon i7 avec SSD, il faut 12 secondes pour créer un itinéraire. Mon idée pour augmenter les performances est de diviser la table de bord en plusieurs tables de niveau de zoom. Je veux dire le niveau identique aux tuiles Google. Au 8e niveau de zoom, par exemple, j'ai 88 tableaux. Chaque table contient un sous-ensemble de routes et leurs zones se chevauchent afin de calculer un itinéraire entre deux points qui ne se trouvent pas à une distance de 290 km l'un de l'autre prend 2 secondes. Au 9ème niveau, le temps de calcul tombe à 0,25 s et nous avons 352 tables. La recréation de tous les graphiques dans le cas où nous éditons des routes ne prend pas plus d'une heure. La manière radicale d'augmenter la vitesse de routage est d'utiliser l'algorithme Floyd-Warshall. Mais personne ne sait combien il faut pour calculer la matrice précédente sur autant d'arêtes.
la source