Вы можете сохранить свои объекты в столбце GEOGRAPHY
и создать SPATIAL INDEX
для этого столбца.
К сожалению, SQL Server
реализует пространственные индексы путем разбиения поверхности и сохранения идентификаторов плитки в виде простого индекса B-Tree
, поэтому простой ORDER BY STDistance
не будет работать (ну, он будет работать, но не будет использовать индекс ).
Вместо этого вам нужно будет сделать запрос, подобный следующему:
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
Таким образом, SQL Server
сначала будет искать дороги в пределах 1
километра от вашей точки, затем в пределах 2
километров и т. Д. Каждый раз, используя индекс.
Обновление:
Если у вас есть несколько точек в таблице и вы хотите найти ближайшую точку для каждой из них:
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