Bạn có thể lưu trữ các đối tượng của mình trong một GEOGRAPHY
và tạo một SPATIAL INDEX
qua cột này.
Thật không may, SQL Server
triển khai các chỉ mục không gian bằng cách lát bề mặt và lưu trữ các mã nhận dạng ô trong một B-Tree
đơn giản chỉ mục, rất đơn giản ORDER BY STDistance
sẽ không hoạt động (tốt, nó sẽ hoạt động nhưng sẽ không sử dụng chỉ mục).
Thay vào đó, bạn sẽ phải thực hiện một truy vấn tương tự như sau:
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
Bằng cách này, SQL Server
trước tiên sẽ tìm kiếm các con đường trong 1
ki lô mét tính từ điểm của bạn, sau đó trong phạm vi 2
ki lô mét, v.v., mỗi lần sử dụng chỉ mục.
Cập nhật:
Nếu bạn có nhiều điểm trong một bảng và muốn tìm điểm gần nhất cho từng điểm đó:
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