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