2011-01-27 42 views
5

我想要計算gps-point之間的距離,以獲得第一個點和最後一個點之間的完整距離。T-SQL Fastforward光標與foreach

我的問題是:什麼是更快?

  • 要將所有行加載到一個DataTable和 使用 StoredProcedure的具有快進 光標經由的foreach 或
  • Caluclate它計算它在C#.NET的SQL服務器上。

我講約40萬行的大寫金額的。

+1

最快將是在服務器**上計算它**,但**沒有光標** ..... – 2011-01-27 14:15:48

+0

@marc_s:有沒有辦法爲沒有光標的每行添加距離? – mabstrei 2011-01-27 14:19:26

+0

看到我的迴應 - 你沒有給我們很多細節,所以我只能提供一個非常普遍的想法...... – 2011-01-27 14:21:15

回答

4

我肯定會嘗試這樣做在服務器上 - 儘量避免拖累400,000行只是爲了計算(最終)單號。

另外:我會盡力做到這一點沒有光標,如果有可能的話。遊標是SQL Server上的噩夢 - 應該不惜一切代價避免它們。

在你的情況 - 不知道你的詳細的表結構 - 你可以肯定做到如一個以第一個元素開始並且總距離爲0.0的遞歸CTE(公用表表達式),然後遞歸地求和所有其他路點,計算點(x + 1)和點x之間的距離,並且總計爲先前的總數。

最後,你應該有一個CTE,顯示所有的航點,任何兩個航點之間的所有距離,全程總距離。

這CTE會是這樣的:

;WITH Waypoints AS 
(
    -- anchor your query 
    SELECT 
     WaypointID, PrevWaypointID, Long, Lat, 0.0 as Distance, 0.0 as SumOfDistance 
    FROM 
     dbo.Waypoint 
    WHERE 
     PrevWaypointID IS NULL -- or some other condition 

    UNION -- recurse 

    SELECT 
     WaypointID, Long, Lat, 
     dbo.GetDistanceBetween(wp.WaypointID, pts.WaypointID), -- distance 
     pts.SumOfDistance + dbo.GetDistanceBetween(wp.WaypointID, pts.WaypointID) -- sum 
    FROM 
     dbo.Waypoint wp 
    INNER JOIN 
     Waypoints pts ON wp.PrevWaypointID = pts.WaypointID   
    WHERE 
     (some condition; ID = 1 or PreviousWaypointID IS NULL or something) 
) 
SELECT * FROM Waypoints 
3

如果使用的是SQL Server 2008中我會建議您嘗試將它們存儲爲geography類型,然後

declare @point1 geography = 'POINT (-42 84)'; 
declare @point2 geography = 'POINT (-3 10)'; 
select @point1.STDistance (@point2) 

但要真正知道什麼是最快的,你必須嘗試兩者。

2

我的理解是,即使是使用SQL遊標,它仍然是數量級比前端代碼迭代更快。當時,ADO和DAO是有問題的技術,所以隨着ADO.NET和DataSets的出現,事情可能會發生一些變化。但是,我敢打賭,專門爲這種類型的東西設計的T-SQL仍然更有效率。

如果您需要在迭代過程中應用特殊邏輯,則可能會出現異常,但我認爲正確設置的SQL遊標(在後臺執行計算)將優於數據集。

最重要的是要做到這一點,而不將光標放在SQL,如果你能。 。 。

2

如果你使用SQL Server 2008(或更高版本),那麼你可以做使用地理類型的服務器上的所有內容。以下是計算兩點之間距離的示例:

SELECT geography::Point(lat1, lon1, 4326).STDistance(geography::Point(lat2, lon2, 4326)) 

我不確定這是否可以在沒有遊標的情況下使用,但也許可以。

如果您使用的是早期版本的SQL Server,那麼您仍然可以將距離公式自己編寫爲存儲過程,並執行服務器端的所有操作。

將整個集合下載到客戶端並進行所有客戶端計算幾乎肯定會花費更長時間,因爲下載時間將比計算時間大得多。