sql >> Database >  >> RDS >> PostgreSQL

Zoekopdracht op coördinaten duurt te lang - opties om te optimaliseren?

U zult veel beter af zijn met het gebruik van een ruimtelijke index die een R-tree gebruikt (in wezen een tweedimensionale index, die werkt door de ruimte in hokjes te verdelen), en veel beter zal presteren dan groter dan, minder dan vergelijkingen op twee afzonderlijke lat. , lon-waarden op dit soort query. U moet echter eerst een type geometrie maken, dat u vervolgens indexeert en in uw query gebruikt in plaats van de afzonderlijke lat/lon-paren die u momenteel gebruikt.

Het volgende zal een type geometrie maken, het vullen en er een index aan toevoegen, zodat het een punt is en in lat/lon, bekend als 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);

Vervolgens kunt u de volgende query uitvoeren om uw gebeurtenissen te krijgen, die een ruimtelijke kruising zullen gebruiken, die uw ruimtelijke index zou moeten gebruiken:

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;

Je maakt het begrenzingsvak voor je snijpunt door ST_MakeBOX2D te gebruiken met twee sets punten, die zich op diagonale hoeken van het begrenzingsvak bevinden, dus de SW en NE of de NW en SE-paren zouden beide werken.

Wanneer u hier uitleg over uitvoert, zou u moeten ontdekken dat de ruimtelijke index is opgenomen. Dit zal veel beter presteren dan twee afzonderlijke indexen op lon- en lat-kolommen, omdat u slechts één geïndexeerde, geoptimaliseerd voor ruimtelijk zoeken, in plaats van twee B-trees raakt. Ik realiseer me dat dit een andere manier is om het te doen en je oorspronkelijke vraag niet beantwoordt, behalve indirect.

BEWERKEN: Mike T heeft het zeer goede punt gemaakt dat het voor het zoeken naar selectiekaders in 4326 geschikter en sneller is om een ​​geometriegegevenstype te gebruiken en de &&-operator aangezien de SRID sowieso wordt genegeerd, bijvoorbeeld

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



  1. PostgreSQL-tekst/bytea-kolom migreren naar een groot object?

  2. Waarom retourneert de functie PostgreSQL json_agg() geen lege array?

  3. Android-applicatie om afbeelding naar MySQL te verzenden

  4. Forceer Oracle Drop Global Temp Table