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