Kiedy NIE należy używać indeksu przestrzennego?


29

Pytam o to, ponieważ głównie pracowałem z Oracle, ale przez ostatni rok podwoiłem się z PostGIS i SQLServer 2008. Większość funkcji przestrzennych w Oracle nie będzie działać bez indeksu przestrzennego zwracającego błąd ORA-13226:

13226, 00000, „interfejs nieobsługiwany bez indeksu przestrzennego” // * Przyczyna: Tabela geometrii nie ma indeksu przestrzennego. // * Działanie: Sprawdź, czy tabela geometrii, do której odwołuje się operator przestrzenny, ma indeks przestrzenny.

Dla mnie ma to sens. Wykonujesz zapytanie przestrzenne = musisz mieć indeks przestrzenny. Ale o ile rozumiem, ani PostGIS, ani SQL Serve tego nie wymagają. PostGIS wydaje się nawet mieć funkcje (_ * np. _STContains), które WYRAŹNIE nie będą używać indeksu przestrzennego.

Pytanie brzmi: czy są jakieś przypadki, w których NIE powinieneś używać indeksu przestrzennego ?. Niekoniecznie, czy jest to podejście „weź lub zostaw”, tzn. Nie zrobi to żadnej różnicy, ale gdzie NIE użycie indeksu przestrzennego poprawi wydajność? Dla mnie ostatnie zdanie jest sprzecznością, ale poza tym, dlaczego PostGIS miałby zapewniać te funkcje?


3
Jeśli chcesz zobaczyć, gdzie indeks spowalnia pracę w PostGIS SET enable_seqscan = off. Zmusi to PostgreSQL do używania indeksów za każdym razem. Porównaj prędkości z tym.
Sean

Dziękujemy za rozpoczęcie tego wątku. Przelewam informacje do sieci, próbując dowiedzieć się, dlaczego moja organizacja (rząd) nie wykorzystuje wskaźników przestrzennych (a nawet atrybutów) w swoich klasach i tabelach funkcji Oracle / SDE. Teraz mam kilka argumentów do przedstawienia, więc nie muszę wyciągać włosów, czekając na odpowiedź.
Mike

Odpowiedzi:


12

mapoholic,

Ogólnie rzecz biorąc, nie ma powodu, aby wykonywać zapytania przestrzenne bez indeksu przestrzennego, chyba że mamy do czynienia z naprawdę małymi tabelami. Mimo to użyłbyś ST_, które nie używają indeksu, ale mają & & indeksowane operatory skrzynki zwarciowej. funkcje rozpoczynające się od _ST nie są przeznaczone dla użytkowników końcowych. Powodem ich istnienia jest to, że muszą. Indeksy przestrzenne PostGIS używają wbudowanego SQL do wymuszania użycia indeksu - _ST jest zwykle wykonywane przez GEOS, a && to indeks, który może zostać zmieniony. Więc _ST są naprawdę artefaktem implementacyjnym.

w skrócie - nie jest to jedna funkcja, aby można było zmienić kolejność operacji indeksu, aby zachodziła naraz przed bardziej intensywną kontrolą przestrzenną.


na zdrowie LR1234567. Myślę, że tego właśnie szukałem.
mapoholic

25

Jeśli Twój zestaw danych jest często dodawany i aktualizowany, wówczas instrukcje INSERT, DELETE i UPDATE, które powodują przebudowanie indeksu, mogą spowolnić bazę danych.

W przypadku wstawień zbiorczych, takich jak ładowanie całego zestawu danych OSM do bazy danych, szybsze może być upuszczenie indeksów i utworzenie ich ponownie później.

Jeśli bardziej efektywne jest zignorowanie indeksu (na przykład tabela jest wystarczająco mała, aby można ją było załadować do pamięci), procesor zapytań bazy danych powinien to zrobić automatycznie.

Spodziewałbym się, że głównym powodem, dla którego zezwalamy na uruchamianie zapytań bez indeksu przestrzennego, jest mierzenie korzyści wydajnościowych uzyskiwanych za pomocą indeksu, bez konieczności jego upuszczania.

Wreszcie, jeśli chcesz wykazać ogromny wzrost wydajności zapytań i map, możesz opóźnić tworzenie indeksów do odpowiedniego momentu w rozwoju systemu ...


3
(+1) Czy w tej ostatniej uwadze wyczuwam odrobinę cynizmu? :-)
whuber

Wcale nie ;-) Ale upuszczanie / odtwarzanie dokładnie dostrojonych indeksów jest przydatną odpowiedzią na „Dlaczego X poświęcił wiele czasu na zmiany w bazie danych”?
geographika

Dzięki geograficznie - i zgadzam się z uwagą Whubera! ;-) Rozumiem, że upuszczałbyś / dezaktywowałeś wskaźniki przestrzenne podczas masowego ładowania - lub wszystkie wskaźniki dla sprawy, ale nie możesz wymyślić powodu, dla którego kiedykolwiek zrobiłbyś zapytanie przestrzenne BEZ użycia indeksu przestrzennego? Jeśli tabela jest wystarczająco mała, użycie indeksu może nie mieć znaczenia - wystarczająco uczciwe - ale rezygnuje z używania indeksu ?. Nie wiem, myślę, że jestem po prostu zdumiony więcej o istnieniu funkcji PostGIS non-przestrzenno-indeks ...
mapoholic

2
Jeśli tabela jest wystarczająco mała i mieści się w pamięci, użycie indeksu wymaga losowego dostępu do dysku, co jest droższe niż skanowanie sekwencyjne. wiki.postgresql.org/wiki/…
Sean

2
@mapoholic - _ST_Contains może pozostać po tym, jak trzeba było ręcznie wykonać filtr wstępny danych, sądząc z old.nabble.com/…
geographika

10

Myślę, że jest to sugerowane, ale NIE użyłbym indeksu przestrzennego do zapytania, gdybym miał indeks nieprzestrzenny, którego mógłbym użyć zamiast tego. Na przykład mam 2 113 450 punktów, które obejmują Stany Zjednoczone załadowane do tabeli. Gdybym chciał wyciągnąć wszystkie punkty, które znajdowały się w stanie Alaska, mógłbym albo wykonać zapytanie przestrzenne, które użyłoby indeksu GIST dla geometrii punktów, aby porównać z geometrią stanu Alaski, LUB, mógłbym po prostu użyć pole „state_alpha” w danych punktów (które jest również indeksowane), aby zwrócić wszystkie punkty, które mają „state_alpha” = „AK”.

„Gdzie jest tego część przestrzenna”, pytasz? Cóż, jeśli muszę zebrać trochę dalszych analiz przestrzennych na punktach Alaska po ich zebraniu, szybciej jest zebrać te geometrie punktów, używając najpierw zapytania nieprzestrzennego. Oznacza to również, że w przypadku naprawdę dużych zestawów danych korzyść daje dodanie pola wyszukiwania (lub tabeli). Znów wiem, że jest to prawdopodobnie oczywiste dla wszystkich, ale wspominam o tym tylko dlatego, że napotkałem go w przeszłości z globalnymi zestawami danych, które były tylko indeksowane przestrzennie, a gdzie powszechnym zapytaniem było „wszystkie funkcje w danym kraju”. Zdecydowanie poprawiliśmy wydajność, dodając indeksowane pole country_fips.

Poniżej znajdują się niektóre wyniki z EXPLAIN ANALYZE, które potwierdzają to. (UWAGA: Próbowałem uczynić zapytanie przestrzenne tak wydajnym, jak to możliwe, używając zapytania BBOX. Użycie konturów stanu tylko spowolniłoby go).

# explain analyze select count(*) from gnis_names where state_alpha = 'AK';
Aggregate  (cost=57359.45..57359.46 rows=1 width=0) (actual time=76.606.. 76.607 rows=1 loops=1)
<snip>
Total runtime: 76.676 ms

# explain analyze select count(*) from gnis_names where the_geom && GeomFromText('POLYGON((-179.14734 51.219862,-179.14734 71.3525606439998,179.77847 71.3525606439998,179.77847 51.219862,-179.14734 51.219862))',4326);
Aggregate  (cost=27699.86..27699.87 rows=1 width=0) (actual time=86.523..86.524 rows=1 loops=1)
<snip>
Total runtime: 86.584 ms 

wielkie dzięki za to. To może wydawać się oczywiste, kiedy to mówisz, ale moją pierwszą myślą byłoby uruchomienie zapytania przestrzennego, a nie tylko atrybutu. +1 za to!
mapoholic

0

Właśnie zauważyłem to oświadczenie

Dla mnie ma to sens. Wykonujesz zapytanie przestrzenne = musisz mieć indeks przestrzenny

Dla mnie to nie ma żadnego sensu i myślę, że zarówno SQL Server, jak i Postgis wykonują lepszą pracę lub przynajmniej nie zawracają ci głowy szczegółami wydajności. W rzeczywistości zarówno SQL Server, jak i Postgis czasami nawet nie używają indeksu przestrzennego (przywróć do pełnego skanowania tabeli).

W przypadku Oracle należy utworzyć indeks i dlatego należy wypełnić user_sdo_geom_metadata.

Porównując to z indeksami alfanumerycznymi, są one dostępne ze względu na wydajność, instrukcja SQL powinna z nią pracować i bez niej.

W bazie danych Oracle upuść indeks, a otrzymasz mnóstwo błędów i aplikacji, które nie będą mogły korzystać z zapytań przestrzennych, a zatem nie będą działać.

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.