PósGIS
Não armazene lat e long em uma mesa como essa. Em vez disso, use uma geometria PostGIS ou tipo de geografia .
CREATE EXTENSION postgis;
CREATE TABLE foo (
geog geography;
);
CREATE INDEX ON foo USING gist(geog);
INSERT INTO foo (geog)
VALUES (ST_MakePoint(x,y));
Agora, quando você precisar consultá-lo, poderá usar KNN (
<->
)
que realmente fará isso em um índice. SELECT *
FROM foo
ORDER BY foo.geog <-> ST_MakePoint(x,y)::geography;
Em sua consulta, você tem explicitamente
HAVING distance < 5
. Você pode fazer isso no índice também. SELECT *
FROM foo
WHERE ST_DWithin(foo.geog, ST_MakePoint(x,y)::geography, distance_in_meters)
ORDER BY foo.geog <-> ST_MakePoint(x,y)::geography;
Isso garante que nada seja retornado se todos os pontos estiverem fora de
distance_in_meters
. Além disso, x e y são números decimais
ST_MakePoint(46.06, 14.505)