Quel est le meilleur hack pour importer de grands ensembles de données dans PostGIS?

21

Je dois importer des fichiers Shapefiles volumineux (> 1 million d'enregistrements) dans PostGIS, et je me suis demandé quelle était la meilleure façon de le faire.

entrez la description de l'image ici

Dans ma question, j'ai utilisé le mot "hack", au lieu d'outil, exprès parce que je pense que ce n'est pas tant une question de quel outil, mais de quel ensemble d'étapes ou de paramètres de configuration à utiliser. Jusqu'à présent, j'ai essayé le plugin SPIT (QGIS), l' outil shp2pgsql Postgis et l' outil GDAL ogr2ogr . Vous pouvez consulter mon avis complet sur ce post. Jusqu'à présent, je trouve que tous ne répondent vraiment pas lorsqu'il s'agit d'un grand ensemble de données. Je me demandais si quelqu'un avait rencontré un problème similaire et si vous pouviez partager quelque chose sur l'approche.

double octet
la source

Réponses:

18

J'ai fait un test pour vous:

  • PostgreSQL 9.3
  • PostGIS 2.1
  • Windows 7
  • Processeur i7 3770@3,4 GHz
  • GDAL 2.0-dev 64 bits
  • fichier de formes de 1,14 million de polygones, taille de fichier 748 Mo

Commande Ogr2ogr:

ogr2ogr -f PostgreSQL PG: "dbname = 'databasename' host = 'addr' port = '5432' user = 'x' password = 'y'" test.shp --config PG_USE_COPY YES -nlt MULTIPOLYGON

Temps total: 1 minute 30 sec

user30184
la source
Merci pour votre réponse! Cela semble vraiment rapide; Je pense que cela n'a peut-être pas fonctionné pour moi car je n'ai pas utilisé l'indicateur --config PG_USE_COPY YES; J'ai réussi à l'importer rapidement en utilisant: psql target-db -U <admin user> -p <port> -h <DB instance name> -c "\ copy source-table from 'source-table.csv' with DELIMITER ' , '"(puis reconstruire la géométrie), ce qui, je suppose, est une approche similaire.
double octet
COPY est plus rapide et sera la valeur par défaut dans GDAL 2.0 lorsque les données sont écrites dans de nouvelles tables. Lorsque des insertions sont utilisées, la taille par défaut des transactions (contrôlée avec le paramètre -gt) n'était que de 200 fonctionnalités avant GDAL version 1.11 lorsqu'elle a été augmentée à 20000 fonctionnalités. Des transactions plus importantes signifient moins de transactions et cela peut entraîner une accélération énorme.
user30184
4
L'utilisation de COPY est la clé, et vous obtiendrez probablement une traduction encore plus rapide avec shp2pgsql et l'indicateur -D. shp2pgsql -D test.shp | psql testdb
Paul Ramsey
Paul, shp2pgsql -D est-il le même que COPY? Pas clair d'après les documents qui disent que cela utilise le format "dump", mais je ne suis pas sûr de ce que cela signifie même pour une opération de téléchargement (par opposition à une sauvegarde / restauration). Je remarque que shp2pgsql-gui a une option "Charger les données en utilisant COPY plutôt que INSERT", mais pas d'option "dump format", donc ai-je raison de supposer que ce sont les mêmes?
Lee Hachadoorian
Oui, -D est identique à l'utilisation de COPY.
Darrell Fuhriman
9

Après les suggestions de user30184 , Paul Ramsey et mes propres expériences. J'ai décidé de répondre à cette question.

Je n'ai pas mentionné dans cette question que j'importais des données vers un serveur distant. (bien qu'il soit décrit dans le billet de blog auquel je fais référence). Les opérations telles que les insertions sur Internet sont soumises à une latence du réseau. Il n'est peut-être pas inutile de mentionner que ce serveur est sur Amazon RDS , ce qui m'empêche de ssh vers la machine et d'exécuter des opérations localement.

Dans cet esprit, j'ai repensé mon approche, en utilisant la directive "\ copy" pour promouvoir un vidage des données dans une nouvelle table. Je pense que cette stratégie est une clé essentielle, qui a également été mentionnée dans les commentaires / réponses à cette question.

psql database -U user -h host.eu-west-1.rds.amazonaws.com -c "\copy newt_table from 'data.csv' with DELIMITER ','"

Cette opération a été incroyablement rapide. Depuis que j'ai importé un csv, j'ai ensuite eu tout le travail de remplir la géométrie, d'ajouter un index spatial, etc. C'était encore remarquablement rapide, car j'exécutais alors des requêtes sur le serveur .

J'ai décidé de comparer également les suggestions de user30184 , Paul Ramsey . Mon fichier de données était un fichier de formes ponctuelles avec 3035369 enregistrements et 82 Mo.

L'approche ogr2ogr (utilisant la directive PG_USE_COPY) s'est terminée en 1:03:00 m, ce qui est toujours * bien meilleur qu'auparavant.

L'approche shp2pgsql (utilisant la directive -D) s'est terminée en 00:01:04 m seulement.

Il vaut la peine de dire que ogr2ogr a créé un index spatial pendant l'opération, contrairement à shp2pgsql. Je découvre qu'il est beaucoup plus efficace de créer l'index après avoir effectué l'importation, plutôt que de gonfler l'opération d'importation avec ce type de demande.

La conclusion est la suivante: shp2pgsql, lorsqu'il est correctement paramétré, est extrêmement bien adapté pour effectuer des importations importantes, à savoir celles à héberger dans Amazon Web Services.

Table spatiale avec plus de 3 millions d'enregistrements, importée à l'aide de shp2pgsql

Vous pouvez lire une description plus détaillée de ces conclusions, sur la mise à jour de cet article.

double octet
la source
Avant d'accuser trop GDAL, consultez la documentation. Ogr2ogr n'est pas impliqué, c'est plutôt le pilote GDAL PostGIS et il a une option pour désactiver l'index spatial gdal.org/drv_pg.html . L'utilisation avec ogr2ogr consiste à ajouter -lco SPATIAL_INDEX = NO. GDAL a également un autre pilote pour PGDump qui pourrait mieux convenir à votre cas d'utilisation gdal.org/drv_pgdump.html . Peut-être que vous mentionnerez également ces choses dans votre blog.
user30184
1
La différence de vitesse 1:03:00 et 00:01:04 entre ogr2ogr et shp2pgsql est énorme. Je suis sûr que c'est réel mais le résultat ne peut pas être généralisé. Si vous testez avec une base de données PostGIS locale, la différence sera bien moindre. Votre résultat signifie que quelque chose va très mal pour ogr2ogr. Quelle version de GDAL avez-vous utilisée? S'il est plus ancien que la version 1.11, avez-vous essayé d'augmenter la taille des transactions en ajoutant quelque chose comme -gt 60000?
user30184
1
Ce n'est pas un gonflement supplémentaire de créer dans l'index lors de l'importation que de le faire ensuite. La commande émise est exactement la même et le temps qu'elle prend exactement la même. De plus, si vous voulez que shp2pgsql ajoute l'index, il vous suffit d'ajouter l'option '-I'.
Darrell Fuhriman
Merci pour vos commentaires. Mon étude de cas était une importation vers un Postgres fonctionnant sur AWS, il était donc important pour moi que la transaction se déroule bien sur le réseau. J'ai utilisé l'indicateur PG_USE_COPY sur ogr2ogr, mais je n'ai pas essayé le pilote PGDump, qui de la page de manuel semble prometteur. Ma version de GDAL est 1.7. Je devrais tout comparer en égalité de conditions (avec ou sans l'index), mais d'après ce que Daniel me dit, ce n'est pas le problème, car je crée l'index assez rapidement dans la base de données ...
doublebyte
1
Oui, les études de cas sont acceptables si elles ont été écrites afin que les lecteurs n'aient pas l'impression que les résultats peuvent être généralisés à ce qu'ils représentent réellement. Par exemple, il serait bon de mentionner que vous avez fait le test avec une version GDAL âgée de 5 ans et que certains développements peuvent ou non se produire depuis. Votre version a certainement besoin d'une plus grande valeur -gt pour bien fonctionner, mais de toute façon cela n'a pas beaucoup de sens de tester avec une version GDAL plus ancienne que 1.10.
user30184