Du kan gemme dine objekter i en GEOGRAPHY
kolonne og opret et SPATIAL INDEX
over denne kolonne.
Desværre, SQL Server
implementerer rumlige indekser ved at flisebelægge overfladen og gemme fliseidentifikatorerne i et almindeligt B-Tree
indeks, så almindelig ORDER BY STDistance
vil ikke virke (godt, det vil virke, men vil ikke bruge indekset).
I stedet skal du lave en forespørgsel, der ligner denne:
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å denne måde SQL Server
vil først søge efter veje inden for 1
kilometer fra dit punkt og derefter inden for 2
kilometer osv., hver gang ved hjælp af indekset.
Opdatering:
Hvis du har flere punkter i en tabel og ønsker at finde det nærmeste punkt for hver af 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