Можете да съхранявате вашите обекти в 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