Wzrost wydajności dzięki wskaźnikowi GIST dla punktu w zapytaniu wielokąta


10

Mam dwie tabele: lokalizacje (id, region_id, the_geom) i regiony (id, the_geom). Dla każdego punktu lokalizacji chcę określić region, w którym się znajduje:

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

Czy ma sens budowanie indeksu GIST na punktach lokalizacji? Zbuduję indeks na wielokątach regionu, ale nie jestem pewien co do punktów. Czy przyspieszyłoby to zapytanie?

Odpowiedzi:


14

Krótka odpowiedź: Nie. W przypadku tego typu zapytania UPDATE aktualizujemy każdy wiersz w locations(„Seq Scan”), a indeks GiST włączony the_geomw in regionsjest wystarczający, aby pomóc ograniczyć wiersze, od których ST_Withinwarunek może sparować odpowiedni wiersz regions.


Dłuższa odpowiedź: magią tego rozwiązania jest porównanie tego, co otrzymujesz z zapytania wyjaśniającego . W pgAdmin III znajduje się przycisk „Wyjaśnij zapytanie” w górnej części edytora zapytań lub w pgsql, po prostu poprzedź zapytanie słowem „wyjaśnij”:

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)

Nie musisz rozumieć wszystkiego, co jest tutaj zakaszlowane. Kluczową rzeczą do zobaczenia jest to, że w najbardziej wewnętrznej części (SubPlan 1) wskazuje „Indeks” (= używa indeksu, który może znacznie przyspieszyć), a nie „Skan sekwencyjny” (= skanowanie sekwencji, tj. Sprawdzanie każdego wiersz, aby zobaczyć, czy jest w środku, co może być wolniejsze). Jeśli dodasz / usuniesz indeks GiST locations, wynik tego zapytania wyjaśniającego jest dokładnie taki sam, więc wydajność zapytania powinna być taka sama.

Jeśli jednak zrobisz coś głupiego i usuniesz swój indeks GiST regions, zobaczysz inny plan zapytań z tego samego zapytania, co powyżej:

                             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)

Ważną rzeczą do zobaczenia między tymi dwoma zapytaniami wyjaśniającymi są szacunkowe koszty maksymalne .. kontrast 74,05 tutaj do 8,52 wcześniej, więc można oczekiwać, że to zapytanie będzie wolniejsze.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.