PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Zapytanie według współrzędnych trwa zbyt długo - opcje do optymalizacji?

Znacznie lepiej będzie, jeśli użyjesz indeksu przestrzennego, który używa R-drzewa (zasadniczo dwuwymiarowego indeksu, który działa poprzez podzielenie przestrzeni na pola) i będzie działać znacznie lepiej niż większe niż mniejsze niż porównania na dwóch oddzielnych szerokościach , wartości lon w tego rodzaju zapytaniach. Najpierw jednak musisz utworzyć typ geometrii, który następnie zindeksujesz i użyjesz w zapytaniu zamiast oddzielnych par szerokości/długości, których obecnie używasz.

Poniższe polecenie utworzy typ geometrii, wypełni go i doda do niego indeks, upewniając się, że jest to punkt i szerokość/długość, znany jako EPSG:4326

alter table event add column geom geometry(POINT, 4326);
update event set geom=ST_SetSrid(ST_MakePoint(lon, lat), 4326);
create index ix_spatial_event_geom on event using gist(geom);

Następnie możesz uruchomić następujące zapytanie, aby uzyskać zdarzenia, które będą używać przestrzennych przecięć, które powinny wykorzystywać Twój indeks przestrzenny:

Select * from events where ST_Intersects(ST_SetSRID(ST_MakeBox2D(ST_MakePoint(swLon, swLat), 
    ST_MakePoint(neLon, neLat)),4326), geom) 
order by relevancy desc limit 100;

Tworzysz ramkę graniczną dla swojego przecięcia, używając ST_MakeBOX2D z dwoma zestawami punktów, które będą znajdować się na ukośnych rogach ramki granicznej, tak aby działały pary SW i NE lub NW i SE.

Po uruchomieniu wyjaśnij na tym, powinieneś zauważyć, że indeks przestrzenny jest uwzględniony. Będzie to działać znacznie lepiej niż dwa oddzielne indeksy w kolumnach lon i lat, ponieważ trafisz tylko na jeden indeksowany, zoptymalizowany pod kątem wyszukiwania przestrzennego, a nie na dwa B-drzewa. Zdaję sobie sprawę, że jest to inny sposób na zrobienie tego i nie odpowiada na pierwotne pytanie, z wyjątkiem pośrednich.

EDYTUJ: Mike T bardzo dobrze zauważył, że w przypadku wyszukiwania z obramowaniem w 4326, bardziej odpowiednie i szybsze jest użycie typu danych geometrii i operatora &&, ponieważ SRID i tak zostanie zignorowany, np.

 where ST_MakeBox2D(ST_MakePoint(swLon, swLat), ST_MakePoint(neLon, neLat)) && geom



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Błąd Postgresa podczas aktualizowania danych w kolumnie

  2. Jak dodać 2 punkty wraz z odległością między nimi (SRID =32636)?

  3. Jak mogę zmienić kodowanie bazy danych dla bazy danych PostgreSQL za pomocą sql lub phpPgAdmin?

  4. zapytanie dla mojego administratora pierwszego wiersza, aby nigdy nie usuwać

  5. Jak w NodeJS zapisać obiekt JSON jako tekst za pomocą modułu node-postgres?