sql >> Database teknologi >  >> RDS >> PostgreSQL

Forespørgsel efter koordinater tager for lang tid - muligheder for at optimere?

Du vil være meget bedre stillet ved at bruge et rumligt indeks, der bruger et R-træ (i det væsentlige et todimensionelt indeks, som fungerer ved at opdele rummet i kasser), og vil yde langt bedre end større end mindre end sammenligninger på to separate lat. , lon-værdier på denne type forespørgsel. Du skal dog først oprette en geometritype, som du derefter indekserer og bruger i din forespørgsel i stedet for de separate lat/lon-par, du bruger i øjeblikket.

Følgende vil oprette en geometritype, udfylde den og tilføje et indeks til den, hvilket sikrer, at den er et punkt og i lat/lon, kendt som 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);

Derefter kan du køre følgende forespørgsel for at få dine begivenheder, som vil bruge et rumligt skæringspunkt, som skal bruge dit rumlige indeks:

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;

Du laver afgrænsningsrammen for dit kryds ved at bruge ST_MakeBOX2D med to sæt punkter, som vil være på diagonale hjørner af afgrænsningsrammen, så SW og NØ eller NW og SØ parrene ville begge fungere.

Når du kører forklaring på dette, bør du opdage, at det rumlige indeks er inkluderet. Dette vil fungere meget bedre end to separate indekser på lon og lat kolonner, da du kun rammer én indekseret, optimeret til rumlig søgning, snarere end to B-træer. Jeg er klar over, at dette repræsenterer en anden måde at gøre det på og ikke besvarer dit oprindelige spørgsmål, undtagen indirekte.

EDIT: Mike T har gjort den meget gode pointe, at for afgrænsningsbokssøgninger i 4326 er det mere passende og hurtigere at bruge en geometridatatype og &&-operatoren, da SRID'en alligevel vil blive ignoreret, f.eks.

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



  1. Capistrano med PostgreSQL, fejl:andre brugere får adgang til databasen

  2. Erstat i forespørgselssyntaks

  3. En guide til partitionering af data i PostgreSQL

  4. mySQL-fejl 1040:For mange forbindelser