Sql-Server

一個位置的最小距離;一個點表與一組點 SQL 2012 相比

  • November 16, 2015

我試圖找到最快的方法來找到一個點到點表的最小距離。唯一需要注意的是,我試圖找到最小距離的點表是 150K 單點。

或者更好地解釋表 A 有 150K 行/點,表 B 有 1500 點。我想知道表 A 中的每一行與表 B 中列出的所有行的最小距離是多少。

我有一個計算距離的函式,作為表 A 的添加列。它只需要很長時間。表 B 有一個空間索引。

這就是我所擁有的:

select a.*, 
      dbo.fxn_distance(geography::STPointFromText('POINT(' + 
      CAST([Long] AS VARCHAR(20)) + ' ' + CAST([Lat] AS 
      VARCHAR(20)) +    ')', 4326)) as DistAway
from Table A a

我的功能:

create function fxn_distance
(@pointTableA geography
)
returns float 
as 
begin

declare @distance float

select top 1 @distance = b.GeoLocation.STDistance(@pointTableA) 
from TableB b  
where geolocation.STDistance(@pointTableA) is not null
order by geolocation.STDistance(@pointTableA)

return @distance
end

抱歉,如果我完全是新手,我知道解決方案可能很簡單,但我無法解決這個問題。所以希望澄清一下:我需要傳遞表 A 中每個點的緯度/經度,看看最小距離與表 B 中的每一行相比,對於表 A 中的每一行。我關心實際距離是多少,但不是表 B 中的實際點。

任何幫助表示讚賞。

如果將函式轉換為表值函式,您可能會獲得更好的性能。

在這裡,我設置了測試台:

USE tempdb;
CREATE TABLE dbo.TableA
(
   LAT DECIMAL(10,5)
   , LON DECIMAL(10,5)
);

CREATE TABLE TableB
(
   Geolocation GEOGRAPHY NOT NULL
);
GO

這是表值函式,它基本上是你的函式,除了它返回一個表。

CREATE FUNCTION dbo.fxn_distance
(
   @pointTableA GEOGRAPHY
)
returns table
as return 
(
   SELECT TOP 1 Distance = b.GeoLocation.STDistance(@pointTableA) 
   FROM TableB b  
   WHERE geolocation.STDistance(@pointTableA) IS NOT NULL
   ORDER BY geolocation.STDistance(@pointTableA)
)
GO

在兩個表中分別插入一個簡單的測試行:

INSERT INTO dbo.TableA(LAT, LON)
VALUES (49.0,170.0);

INSERT INTO dbo.TableB(Geolocation)
VALUES (geography::STGeomFromText(
   'LINESTRING(-122.360 47.656, -122.343 47.656)', 4326)
);

使用內聯 TVF 確定最近點的查詢:

SELECT a.*
   , d.Distance --This is the distance calculated by the TVF. 
FROM dbo.TableA a
CROSS APPLY dbo.fxn_distance(geography::STPointFromText('POINT(' + 
      CAST(A.LON AS VARCHAR(20)) + ' ' + CAST(A.LAT AS 
      VARCHAR(20)) + ')', 4326)) d ;

引用自:https://dba.stackexchange.com/questions/121040