2011-01-27 12 views
5

मैं पहले अंतिम बिंदु के बीच पूर्ण दूरी प्राप्त करने के लिए जीपीएस-पॉइंट के बीच की दूरी को कम करना चाहता हूं।टी-एसक्यूएल फास्टफोर्ड कर्सर बनाम फोरैच

मेरा प्रश्न है: तेज़ क्या है?

  • एक DataTable में सभी पंक्तियों लोड करने के लिए और एक fastforward कर्सर के साथ एक StoredProcedure का उपयोग कर foreach या
  • Caluclate यह के माध्यम से ग # .net में यह गणना Sql-सर्वर पर।

मैं लगभग 400,000 पंक्तियों के बारे में बात करता हूं।

+1

सबसे तेज़ यह ** ** सर्वर पर गणना करना होगा, लेकिन ** बिना किसी कर्सर ** ..... –

+0

@marc_s: क्या कर्सर के बिना प्रत्येक पंक्ति के लिए दूरी जोड़ने का कोई तरीका है? – mabstrei

+0

मेरी प्रतिक्रिया देखें - आप हमें बहुत सारे विवरण नहीं दे रहे हैं, इसलिए मैं केवल एक बहुत ही सामान्य विचार प्रदान कर सकता हूं .... –

उत्तर

4

मैं निश्चित रूप से सर्वर पर ऐसा करने का प्रयास करता हूं - केवल एक नंबर (अंत में) की गणना करने के लिए 400'000 पंक्तियों को खींचने से बचने का प्रयास करें।

इसके अलावा: मैं इसे बिना किसी कर्सर के बिना करने की कोशिश करता हूं, यदि कभी भी संभव हो। कर्सर एसक्यूएल सर्वर पर एक दुःस्वप्न हैं - उन्हें हर कीमत से बचा जाना चाहिए।

आपके मामले में - अपनी विस्तृत तालिका संरचना को नहीं जानते - आप निश्चित रूप से ऐसा कर सकते हैं उदा। एक पुनरावर्ती सीटीई (सामान्य तालिका अभिव्यक्ति) जो पहले तत्व और 0.0 की कुल दूरी से शुरू होती है, और उसके बाद बिंदु (x + 1) और बिंदु x के बीच की दूरी की गणना करने, और संक्षेप में सभी अन्य बिंदुओं को जोड़ती है, और संक्षेप में पिछले कुल

अंत में, आपके पास एक सीटीई होना चाहिए जो सभी तरह के बिंदुओं को दिखाता है, किसी भी दो मार्गों के बीच की दूरी, और पूरी यात्रा की कुल दूरी।

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 
+0

ऑर्डर क्या है या मुझे कुछ याद आती है? –

+0

@ जोनास एल्फस्ट्रॉम: आवश्यकतानुसार कोई ऑर्डर नहीं - वहां * एक * पंक्ति है जो एंकर है, और उसके बाद से, यह हमेशा 'SomeRow.PrevWaypointID = पिछला Row.WaypointID' कनेक्शन है - ऑर्डर को एक तरफ के बीच संबंध द्वारा परिभाषित किया जाता है और यह पिछले एक है। –

+0

आह, लिंक्ड सूची निर्माण को याद किया। –

3

आप एसक्यूएल सर्वर 2008 का उपयोग कर रहे हैं, तो मैं उन्हें geography प्रकार के रूप में संग्रहीत करने का प्रयास की सिफारिश करेंगे और उसके बाद

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

लेकिन वास्तव में पता है कि सबसे तेजी से तुम दोनों की कोशिश करना है।

+1

टाइपो? दूसरी पंक्ति 'प्वाइंट 2 घोषित करें' ... '? – MusiGenesis

+0

हां, एक अच्छा पुराना टाइपो था। –

2

मेरे समझ है कि SQL में एक कर्सर का उपयोग कर, यह अभी भी परिमाण के आदेश तेजी से सामने की ओर कोड में पुनरावृत्ति से है। उस समय, एडीओ और डीएओ सवाल में प्रौद्योगिकियां थीं, इसलिए एडीओ.NET और डेटासेट के आगमन के साथ चीजें थोड़ी-थोड़ी बदल गईं।

हालांकि, मैं शर्त लगा रहा हूं कि टी-एसक्यूएल, विशेष रूप से इस प्रकार की चीज़ के लिए डिज़ाइन किया जा रहा है, अभी भी अधिक कुशल है। अगर आप अपने यात्रा के दौरान विशेष तर्क लागू करने की आवश्यकता

अपवाद हो सकता है होगा, लेकिन मैं ssupect कि एक ठीक से पीछे की ओर अपने गणना प्रदर्शन एसक्यूएल कर्सर की स्थापना की,, डेटासेट से बेहतर प्रदर्शन करेगी।

यदि आप सक्षम हैं, तो सबसे अच्छा एसक्यूएल में कर्सर के बिना ऐसा करना होगा। । ।

+0

मैं पोस्ट कर रहा था जबकि अन्य बेहतर जवाब दे रहे थे। । । – XIVSolutions

2

यदि आप एसक्यूएल सर्वर 2008 (या नए) का उपयोग कर रहे हैं, तो आप भूगोल प्रकार का उपयोग कर सर्वर पर सबकुछ कर सकते हैं। यहाँ दो बिंदुओं के बीच दूरी की गणना के लिए एक नमूना है:

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

मैं सुनिश्चित नहीं हूं कि यह एक कर्सर के बिना इस्तेमाल किया जा सकता है, लेकिन शायद।

यदि आप SQL सर्वर का पुराना संस्करण उपयोग कर रहे हैं, तो आप अभी भी एक संग्रहित प्रो के रूप में दूरी सूत्र स्वयं लिख सकते हैं, और सर्वर-साइड सबकुछ भी कर सकते हैं।

क्लाइंट को पूरा सेट डाउनलोड करना और सभी गणना क्लाइंट-साइड करना लगभग निश्चित रूप से अधिक समय लेगा, क्योंकि डाउनलोड समय गणना समय से काफी बड़ा होगा।

संबंधित मुद्दे