Index spatial PostgreSQL / PostGIS - pas d'accélération

15

J'ai une table spatiale dans une base de données PostgreSQL / PostGIS. Chaque ligne représente un polygone. Il se présente sous la forme suivante:

+----+--------+
|gid |   way  |
+----+--------+
|241 | 01030..|

La colonne géométrique est "way" qui contient la géométrie d'un polygone. En WKT c'est: POLYGON (('....')). Je fais beaucoup de requêtes ST_Contains sur cette table, pour tester si deux polygones sont contenus l'un dans l'autre, par exemple:

Select ST_Contains(a.way, b.way) From table AS a, table AS b Where a.gid = 15 And b.gid = 16

Je me demandais comment accélérer cette requête et ajouté un index spatial sur la table:

CREATE INDEX table_way_gist ON table USING gist(way);

Mais en fait, je ne vois pas d'accélération. Je crée l'index APRÈS avoir rempli la table avec tous les polygones AVANT de faire les requêtes ST_Contains. Faut-il ajouter l'index avant de remplir un tableau? Y a-t-il des exigences spéciales sur la table pour travailler avec l'index? La projection (srid) de la voie de la colonne géométrique est définie sur 900913.

J'utilise: psql (PostgreSQL) 9.1.4 / POSTGIS = "1.5.3"

MichiMichbeck
la source

Réponses:

16

L'index le plus efficace pour la requête exprimée dans votre question est celui sur gid car c'est la seule colonne qui apparaît dans une expression where:

 CREATE INDEX table_gid ON table (gid);

Vous pouvez supprimer en toute sécurité l'index gist car il ne consommera que de l'espace et ralentira les insertions / mises à jour / suppressions.

Longue explication

Comme je l'ai dit, l'index le plus efficace dans votre cas est celui sur gid car il permettra au moteur db de récupérer des lignes plus rapidement (la récupération étant généralement la partie la plus lente du processus). Après cela, il sera probablement préférable de calculer le résultat de la

  ST_Contains(a.way, b.way)

expression sans regarder l'indice. La raison en est que le planificateur de requêtes estimera probablement que le coût supplémentaire de la recherche de l' index gist sur les deux colonnes par rapport à la recherche directe des valeurs a.way et b.way ne vaut pas la peine car le nombre total de lignes à rechercher est probablement très petit, surtout si l'index est unique.

En règle générale, n'oubliez pas que le planificateur privilégiera probablement une analyse de table par rapport à une analyse d'index pour les petits ensembles de données (les tailles des ensembles de données sont estimées en consultant les statistiques de la table).

unicoletti
la source
Cela rend la question plus claire pour moi. Je vais essayer. Donc, si je mets la requête ST_Contains () dans la clause WHERE, l'index spatial devrait en fait être utile? Je pense que je dois réorganiser mon script pour appeler ST_Contains dans la clause WHERE. En ce moment, j'itère tous les polygones et j'en teste toujours deux séparément.
MichiMichbeck
?? vous pensez qu'un index spatial ralentit les choses? C'est une nouveauté pour moi parce que là où je travaille, nous avons des index spatiaux pour chaque table et je me demande si c'est une mauvaise pratique
Luffydude
13

Comme l'a dit unicoletti , l'index gist dans la colonne de géométrie ne fonctionnerait que si vous utilisez ST_Contains () dans l'expression WHERE.

Par exemple, si vous souhaitez connaître tous les polygones qui se contiennent, vous pouvez utiliser quelque chose comme ceci:

SELECT a.gid, b.gid
FROM table AS a, table as b
WHERE a.gid != b.gid and ST_Contains(a.way, b.way)

Dans ce cas, en fonction de la taille de votre table et de la complexité de vos géométries, l'index gist devrait fournir une accélération significative, car ST_Contains commencera par filtrer les polygones en comparant leurs zones de limites avant de vérifier réellement leurs géométries complètes. Vous pouvez voir une petite explication dans le tutoriel OpenGeo .

Alexandre Neto
la source
Oui, je vois, j'ai besoin de cette requête pour impliquer le test de limite d'index. Thx Alexandre. (Je vais marquer unicoletti comme solution, car il a été rapide et m'a
résolu