Gain de performances via l'index GIST pour le point dans la requête de polygone

10

J'ai deux tables: les emplacements (id, region_id, the_geom) et les régions (id, the_geom). Pour chaque point de localisation, je veux déterminer la région dans laquelle il se trouve:

UPDATE locations SET region_id = 
 (SELECT id FROM regions 
  WHERE ST_Within(locations.the_geom,regions.the_geom)
 );

Est-il judicieux de construire un index GIST sur les points de localisation? Je vais construire un index sur les polygones de la région mais je ne suis pas sûr des points. Cela accélérerait-il la requête?

obscur
la source

Réponses:

14

Réponse courte: Non. Avec ce type de requête UPDATE, nous mettons à jour chaque ligne dans locations("Seq Scan"), et l'index GiST activé the_geomdans regionsest suffisant pour aider à limiter les lignes pour que la ST_Withincondition associe la ligne droite à partir de regions.


Réponse plus longue: La magie pour comprendre cela est de comparer ce que vous obtenez de la requête d'explication . Depuis pgAdmin III, il y a un bouton "Expliquer la requête" en haut d'un éditeur de requête, ou depuis pgsql, il suffit de préfixer votre requête avec "expliquer":

postgis=# explain UPDATE locations SET region_id =
postgis-#  (SELECT id FROM regions
postgis(#   WHERE ST_Within(locations.the_geom, regions.the_geom)
postgis(#  );
                                         QUERY PLAN
--------------------------------------------------------------------------------------------
 Seq Scan on locations  (cost=0.00..8755.54 rows=1000 width=110)
   SubPlan 1
     ->  Index Scan using regions_gist_the_geom on regions  (cost=0.00..8.52 rows=1 width=4)
           Index Cond: ($0 && the_geom)
           Filter: _st_within($0, the_geom)
(5 rows)

Vous n'avez pas besoin de comprendre tout ce qui se crache ici. L'élément clé à voir ici est dans la partie la plus interne (SubPlan 1), il indique "Index" (= utilise un index, ce qui pourrait accélérer considérablement les choses), et non "Seq Scan" (= balayage de séquence, c'est-à-dire en vérifiant chaque ligne pour voir si elle est à l'intérieur, ce qui peut être plus lent). Si vous ajoutez / supprimez un index GiST locations, la sortie de cette requête Explain est exactement la même, les performances de la requête doivent donc être identiques.

Cependant, si vous faites quelque chose de stupide et supprimez votre index GiST regions, vous voyez un plan de requête différent de la même requête que ci-dessus:

                             QUERY PLAN
---------------------------------------------------------------------
 Seq Scan on locations  (cost=0.00..74288.00 rows=1000 width=110)
   SubPlan 1
     ->  Seq Scan on regions  (cost=0.00..74.05 rows=1 width=4)
           Filter: (($0 && the_geom) AND _st_within($0, the_geom))
(4 rows)

La chose importante à voir entre les deux requêtes d'explication est les estimations de coût maximum.

Mike T
la source