Du kan lagra dina objekt i en GEOGRAPHY kolumn och skapa ett SPATIAL INDEX över den här kolumnen.
Tyvärr, SQL Server implementerar rumsliga index genom att plattsätta ytan och lagra plattornas identifierare i ett vanligt B-Tree index, så vanlig ORDER BY STDistance kommer inte att fungera (nåja, det kommer att fungera men kommer inte att använda indexet).
Istället måste du göra en fråga som liknar denna:
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
På detta sätt, SQL Server kommer först att söka efter vägar inom 1 kilometer från din punkt, sedan inom 2 kilometer, etc., varje gång du använder indexet.
Uppdatering:
Om du har flera poäng i en tabell och vill hitta den närmaste punkten för var och en av dem:
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