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