Você pode armazenar seus objetos em uma
GEOGRAPHY coluna e crie um SPATIAL INDEX sobre esta coluna. Infelizmente, o
SQL Server implementa índices espaciais ao ladrilhar a superfície e armazenar os identificadores de ladrilho em uma B-Tree simples index, tão simples ORDER BY STDistance não funcionará (bem, funcionará, mas não usará o índice). Em vez disso, você terá que fazer uma consulta semelhante a esta:
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
Dessa forma,
SQL Server primeiro pesquisará estradas dentro de 1 quilômetro do seu ponto, depois dentro de 2 quilômetros, etc., cada vez usando o índice. Atualização:
Se você tiver vários pontos em uma tabela e quiser encontrar o ponto mais próximo para cada um deles:
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