Puoi memorizzare i tuoi oggetti in una GEOGRAPHY
colonna e creare un SPATIAL INDEX
su questa colonna.
Sfortunatamente, SQL Server
implementa gli indici spaziali affiancando la superficie e memorizzando gli identificatori delle tessere in un semplice B-Tree
index, quindi semplice ORDER BY STDistance
non funzionerà (beh, funzionerà ma non utilizzerà l'indice).
Dovrai invece fare una query simile a questa:
DECLARE @mypoint GEOGRAPHY
SET @mypoint = geography::STGeomFromText('POINT(@mylat, @mylon)', 4326);
WITH num (distance) AS
(
SELECT 1000
UNION ALL
SELECT distance + 1000
FROM num
WHERE distance <= 50000
)
SELECT TOP 1 m.*
FROM num
CROSS APPLY
(
SELECT TOP 1 *
FROM mytable
WHERE myroad.STDistance(@mypoint) <= distance
ORDER BY
STDistance(@mypoint)
) m
In questo modo, SQL Server
cercherà prima le strade all'interno di 1
chilometro dal tuo punto, quindi entro 2
chilometri, ecc., utilizzando ogni volta l'indice.
Aggiornamento:
Se hai più punti in una tabella e vuoi trovare il punto più vicino per ciascuno di essi:
WITH num (distance) AS
(
SELECT 1000
UNION ALL
SELECT distance + 1000
FROM num
WHERE distance <= 50000
)
SELECT mp.mypoint, m.*
FROM @mypoints mp
CROSS APPLY
(
SELECT TOP 1 m.*
FROM num
CROSS APPLY
(
SELECT TOP 1 *
FROM mytable
WHERE myroad.STDistance(@mypoint) <= distance
ORDER BY
STDistance(@mypoint)
) m
) m