सेट आधारित एल्गोरिदम / यूडीएफ को कैसे लागू किया जाए


13

मेरे पास एक एल्गोरिथ्म है जिसे मुझे 800K पंक्तियों और 38 कॉलमों वाली तालिका में प्रत्येक पंक्ति के खिलाफ चलाने की आवश्यकता है। एल्गोरिथ्म VBA में लागू किया गया है और कुछ स्तंभों से अन्य स्तंभों में हेरफेर करने के लिए मूल्यों का उपयोग करके गणित का एक गुच्छा करता है।

मैं वर्तमान में SQL को क्वेरी करने के लिए Excel (ADO) का उपयोग कर रहा हूं और हर पंक्ति के माध्यम से एल्गोरिथ्म को लागू करने के लिए क्लाइंट साइड कर्सर के साथ VBA का उपयोग करता हूं। यह काम करता है लेकिन इसे चलाने में 7 घंटे लगते हैं।

वीबीए कोड पर्याप्त जटिल है कि इसे टी-एसक्यूएल में फिर से बनाना बहुत काम आएगा।

मैंने सीएलआर एकीकरण और यूडीएफ के बारे में संभावित मार्गों के रूप में पढ़ा है। मैंने डेटाबेस के करीब जाने के लिए एक SSIS स्क्रिप्ट कार्य में VBA कोड डालने के बारे में भी सोचा लेकिन मुझे यकीन है कि इस प्रकार की प्रदर्शन समस्या के लिए एक विशेषज्ञ पद्धति मौजूद है।

आदर्श रूप में मैं एक समानांतर सेट आधारित तरीके से जितनी संभव हो उतने पंक्तियों (सभी?) के खिलाफ एल्गोरिथ्म को चलाने में सक्षम होऊंगा।

इस प्रकार की समस्या के साथ सबसे अच्छा प्रदर्शन कैसे प्राप्त करें, इस बारे में किसी भी तरह की मदद की भविष्यवाणी की गई है।

--Edit

टिप्पणियों के लिए धन्यवाद, मैं एमएस एसक्यूएल 2014 एंटरप्राइज का उपयोग कर रहा हूं, यहां कुछ और विवरण हैं:

एल्गोरिथ्म समय श्रृंखला डेटा में विशेषता पैटर्न पाता है। एल्गोरिथ्म के भीतर के कार्य बहुपद चौरसाई, विंडोिंग करते हैं, और इनपुट मानदंड के आधार पर ब्याज के क्षेत्रों का पता लगाते हैं, एक दर्जन मूल्यों और कुछ बूलियन परिणाम लौटाते हैं।

मेरा प्रश्न वास्तविक एल्गोरिदम की तुलना में कार्यप्रणाली के बारे में अधिक है: यदि मैं एक ही बार में कई पंक्तियों पर समानांतर गणना प्राप्त करना चाहता हूं, तो मेरे विकल्प क्या हैं।

मैं देखता हूं कि टी-एसक्यूएल में फिर से कोड की सिफारिश की गई है जो बहुत काम की है, लेकिन संभव है, हालांकि एल्गोरिथ्म डेवलपर वीबीए में काम करता है और यह अक्सर बदलता रहता है इसलिए मुझे टी-एसक्यूएल संस्करण के साथ तालमेल रखने की जरूरत है और फिर से सत्यापन करना होगा परिवर्तन।

क्या टी-एसक्यूएल आधारित कार्यों को लागू करने का एकमात्र तरीका है?


3
SSIS आपको अपने डेटा प्रवाह को अच्छी तरह से डिजाइन करने के लिए कुछ मूल समीकरण प्रस्तुत कर सकता है। यह वह कार्य है जिसे आप तब से देख रहे हैं जब आपको पंक्ति गणना द्वारा इस पंक्ति को करने की आवश्यकता होती है। लेकिन उस ने कहा, जब तक आप हमें विशिष्टता (स्कीमा, गणना शामिल नहीं कर सकते हैं और इन गणनाओं को पूरा करने के लिए क्या उम्मीद है) को अनुकूलित करने में मदद करना असंभव है। वे कहते हैं कि असेंबली में चीजें लिखना सबसे तेज़ कोड के लिए बन सकता है लेकिन अगर, मेरी तरह, आप इसे बहुत ही अच्छे से चूसते हैं, तो यह बिल्कुल भी कारगर नहीं होगा
बिलिंक

2
यदि आप प्रत्येक पंक्ति को स्वतंत्र रूप से संसाधित करते हैं, तो आप 800K पंक्तियों को Nबैचों में विभाजित कर सकते हैं और अलग-अलग प्रोसेसर / कंप्यूटरों Nपर अपने एल्गोरिथ्म के उदाहरणों को चला सकते Nहैं। दूसरी ओर, आपकी मुख्य अड़चन क्या है - एसक्यूएल सर्वर से एक्सेल या वास्तविक अभिकलन में डेटा स्थानांतरित करना? यदि आप VBA फ़ंक्शन को तुरंत कुछ डमी परिणाम वापस करने के लिए बदलते हैं, तो पूरी प्रक्रिया में कितना समय लगेगा? यदि अभी भी घंटों लगते हैं, तो डेटा ट्रांसफर में अड़चन है। यदि इसे कुछ सेकंड लगते हैं, तो आपको गणनाओं को करने वाले VBA कोड को अनुकूलित करना होगा।
व्लादिमीर बारानोव

यह फिल्टर है जिसे एक संग्रहीत प्रक्रिया के रूप में कहा जाता है: SELECT AVG([AD_Sensor_Data]) OVER (ORDER BY [RowID] ROWS BETWEEN 5 PRECEDING AND 5 FOLLOWING) as 'AD_Sensor_Data' FROM [AD_Points] WHERE [FileID] = @FileID ORDER BY [RowID] ASC प्रबंधन स्टूडियो में यह फ़ंक्शन जिसे प्रत्येक पंक्तियों के लिए बुलाया जाता है 50mS लेता है
medwar19

1
तो क्वेरी जो 50 एमएस लेता है और 800000 बार (11 घंटे) निष्पादित करता है वह समय है। क्या प्रत्येक पंक्ति के लिए @FileID अद्वितीय है या क्या आप डुप्लिकेट को निष्पादित करने की आवश्यकता की संख्या को कम से कम कर सकते हैं? आप सभी फ़ाइल के लिए रोलिंग एवी को एक बार में एक स्टेजिंग टेबल पर (फ़ाइलआईडी पर विभाजन का उपयोग करें) और फिर प्रत्येक पंक्ति के लिए एक विंडोिंग फ़ंक्शन की आवश्यकता के बिना उस तालिका को क्वेरी करने के लिए पूर्व निर्धारित कर सकते हैं। स्टेजिंग टेबल के लिए सबसे अच्छा सेटअप ऐसा लगता है जैसे यह एक क्लस्टर इंडेक्स पर होना चाहिए (FileID, RowID)
मिकेल एरिकसन

1
सबसे अच्छा यह होगा कि यदि आप किसी तरह प्रत्येक पंक्ति के लिए db को छूने की आवश्यकता को दूर कर सकें। इसका मतलब है कि आपको या तो TSQL जाना होगा और संभवतः रोलिंग एवी क्यू से जुड़ना होगा या प्रत्येक पंक्ति के लिए पर्याप्त जानकारी प्राप्त करनी होगी, ताकि एल्गोरिथ्म की जरूरत की हर चीज पंक्ति पर हो, शायद किसी तरह से इनकोड किया गया हो, जिसमें कई चाइल्ड रो शामिल हों (xml) ।
मिकेल एरिकसन

जवाबों:


8

कार्यप्रणाली के संबंध में, मेरा मानना ​​है कि आप गलत बी-पेड़ को छाल रहे हैं ;-)।

हम क्या जानते हैं:

सबसे पहले, आइए समेकित करें और समीक्षा करें कि हम स्थिति के बारे में क्या जानते हैं:

  • कुछ जटिल गणनाएँ करने की आवश्यकता है:
    • यह इस तालिका की प्रत्येक पंक्ति पर होना चाहिए।
    • एल्गोरिथ्म अक्सर बदलता है।
    • एल्गोरिथ्म ... [उपयोग करता है] कुछ स्तंभों से मानों को अन्य स्तंभों में हेरफेर करने के लिए
    • वर्तमान प्रसंस्करण समय है: 7 घंटे
  • टेबल:
    • 800,000 पंक्तियाँ हैं।
    • 38 कॉलम है।
  • एप्लिकेशन बैक-एंड:
  • डेटाबेस SQL ​​सर्वर 2014, एंटरप्राइज़ संस्करण है।
  • एक संग्रहीत प्रक्रिया है जिसे हर पंक्ति के लिए कहा जाता है:

    • इसे चलाने के लिए 50 ms (मुझे लगता है) पर लगता है।
    • यह लगभग 4000 पंक्तियों को लौटाता है।
    • परिभाषा (कम से कम भाग में) है:

      SELECT AVG([AD_Sensor_Data])
                 OVER (ORDER BY [RowID] ROWS BETWEEN 5 PRECEDING AND 5 FOLLOWING)
                 as 'AD_Sensor_Data'
      FROM   [AD_Points]
      WHERE  [FileID] = @FileID
      ORDER BY [RowID] ASC
      

हम क्या कर सकते हैं:

अगला, हम इन सभी डेटा बिंदुओं को एक साथ देख सकते हैं कि क्या हम अतिरिक्त विवरणों को संश्लेषित कर सकते हैं जो हमें एक या एक से अधिक बोतल गर्दन खोजने में मदद करेंगे, और या तो एक समाधान की ओर इशारा करेंगे, या कम से कम कुछ संभव समाधानों का शासन करेंगे।

टिप्पणियों में विचार की वर्तमान दिशा यह है कि मुख्य मुद्दा SQL सर्वर और एक्सेल के बीच डेटा स्थानांतरण है। क्या वास्तव में मामला है? यदि संग्रहीत प्रक्रिया को 800,000 पंक्तियों में से प्रत्येक के लिए कहा जाता है और प्रत्येक कॉल (यानी प्रत्येक पंक्ति) के अनुसार 50 एमएस लेता है, जो 40,000 सेकंड (एमएस नहीं) को जोड़ता है। और वह 666 मिनट (hhmm; ;-), या सिर्फ 11 घंटे से अधिक) के बराबर है। फिर भी पूरी प्रक्रिया को चलाने में केवल 7 घंटे लगने की बात कही गई। हमारे पास कुल समय में पहले से ही 4 घंटे हैं, और हमने गणना करने या परिणामों को SQL सर्वर पर वापस करने के लिए समय भी जोड़ा है। इसलिए यहां कुछ ठीक नहीं है।

संग्रहीत प्रक्रिया की परिभाषा को देखते हुए, इसके लिए केवल एक इनपुट पैरामीटर है @FileID; कोई फिल्टर नहीं है @RowID। इसलिए मुझे संदेह है कि निम्नलिखित दो परिदृश्यों में से एक हो रहा है:

  • यह संग्रहित प्रक्रिया वास्तव में प्रत्येक पंक्ति के अनुसार नहीं मिलती है, बल्कि प्रत्येक के अनुसार होती है @FileID, जो लगभग 4000 पंक्तियों में दिखाई देती है। यदि बताई गई 4000 पंक्तियाँ काफी सुसंगत राशि हैं, तो 800,000 पंक्तियों में समूह में से केवल 200 हैं। और 200 प्रत्येक 7 घंटे में केवल 10 सेकंड के लिए प्रत्येक मात्रा में 50 एमएस ले रहा है।
  • यदि यह संग्रहित प्रक्रिया वास्तव में हर पंक्ति के लिए कहलाती है, तो पहली बार एक नया समय @FileIDबीतने के बाद बफ़र पूल में नई पंक्तियों को खींचने में थोड़ा समय नहीं लगेगा, लेकिन फिर अगले 3999 में आम तौर पर पहले से ही होने के कारण तेजी से वापसी होगी। कैश्ड, है ना?

मुझे लगता है कि इस "फ़िल्टर" संग्रहित प्रक्रिया, या SQL सर्वर से एक्सेल में किसी भी डेटा स्थानांतरण पर ध्यान केंद्रित करना एक लाल हेरिंग है

फिलहाल, मुझे लगता है कि अभाव प्रदर्शन के सबसे प्रासंगिक संकेतक हैं:

  • 800,000 पंक्तियाँ हैं
  • ऑपरेशन एक समय में एक पंक्ति पर काम करता है
  • डेटा को SQL सर्वर पर वापस सहेजा जा रहा है, इसलिए "[उपयोग करता है] कुछ कॉलमों से मानों को अन्य स्तंभों में हेरफेर करने के लिए " [मेरे चरण चरण;; ]]

मुझे संदेह है कि:

  • जबकि डेटा पुनर्प्राप्ति और गणना में सुधार के लिए कुछ जगह है, जिससे उन बेहतर प्रसंस्करण समय में एक महत्वपूर्ण कमी की राशि नहीं होगी।
  • प्रमुख अड़चन 800,000 अलग-अलग UPDATEबयान जारी कर रही है , जो 800,000 अलग-अलग लेनदेन है।

मेरी सिफारिश (वर्तमान में उपलब्ध जानकारी के आधार पर):

  1. सुधार का आपका सबसे बड़ा क्षेत्र एक समय में कई पंक्तियों को अपडेट करना होगा (यानी एक लेनदेन में)। आपको प्रत्येक के FileIDबजाय प्रत्येक के संदर्भ में काम करने के लिए अपनी प्रक्रिया को अद्यतन करना चाहिए RowID। इसलिए:

    1. FileIDकिसी सरणी में किसी विशेष की सभी 4000 पंक्तियों में पढ़ें
    2. सरणी में उन तत्वों का प्रतिनिधित्व होना चाहिए जिनमें फ़ील्ड में हेरफेर किया जा रहा है
    3. सरणी के माध्यम से चक्र, प्रत्येक पंक्ति को संसाधित करना जैसा कि आप वर्तमान में करते हैं
    4. एक बार सरणी में सभी पंक्तियों (अर्थात इस विशेष के लिए FileID) की गणना की गई है:
      1. लेन-देन शुरू करें
      2. प्रत्येक को प्रत्येक अद्यतन कॉल करें RowID
      3. यदि कोई त्रुटि नहीं है, तो लेनदेन करें
      4. यदि कोई त्रुटि हुई है, तो रोलबैक और उचित रूप से संभालें
  2. यदि आपका क्लस्टर्ड इंडेक्स पहले से परिभाषित नहीं है, (FileID, RowID)तो आपको उस पर विचार करना चाहिए (जैसा कि @MikaelEriksson ने प्रश्न पर टिप्पणी में सुझाया है)। यह इन सिंगलटन UPDATE को मदद नहीं करेगा, लेकिन यह कम से कम समग्र संचालन में सुधार करेगा, जैसे कि आप उस "फ़िल्टर" संग्रहीत कार्यविधि में क्या कर रहे हैं क्योंकि वे सभी पर आधारित हैं FileID

  3. आपको तर्क को संकलित भाषा में स्थानांतरित करने पर विचार करना चाहिए। मैं एक .NET WinForms ऐप या यहां तक ​​कि कंसोल ऐप बनाने का सुझाव दूंगा। मैं कंसोल ऐप पसंद करता हूं क्योंकि यह एसक्यूएल एजेंट या विंडोज शेड्यूल्ड टास्क के जरिए शेड्यूल करना आसान है। इससे कोई फर्क नहीं पड़ता कि यह VB.NET या C # में किया गया है। VB.NET आपके डेवलपर के लिए अधिक प्राकृतिक फिट हो सकता है, लेकिन फिर भी कुछ सीखने की अवस्था होगी।

    मुझे SQLCLR में जाने के लिए इस बिंदु पर कोई कारण नहीं दिखता है। यदि एल्गोरिथ्म बार-बार बदलता है, तो इससे हर समय असेंबली को फिर से तैनात करना होगा। कंसोल ऐप को फिर से बनाना और .exe को नेटवर्क पर उचित साझा फ़ोल्डर में रखा जाना चाहिए जैसे कि आप बस एक ही प्रोग्राम चलाते हैं और यह हमेशा अप-टू-डेट रहने के लिए होता है, ऐसा करने के लिए काफी आसान होना चाहिए।

    मुझे नहीं लगता कि टी-एसक्यूएल में प्रसंस्करण को पूरी तरह से स्थानांतरित करने में मदद मिलेगी यदि समस्या मुझे संदेह है और आप एक समय में केवल एक अद्यतन कर रहे हैं।

  4. यदि प्रोसेसिंग को .NET में ले जाया जाता है, तो आप टेबल-वेल्यूड पैरामीटर्स (टीवीपी) का उपयोग कर सकते हैं, ताकि आप ऐरे को एक संग्रहीत प्रक्रिया में पास करेंगे जो UPDATEकि टीवीपी टेबल चर के लिए एक JOINs को कॉल करेगा और इसलिए यह एक एकल लेनदेन है । टीवीपी को 4000 INSERTएस को एकल लेनदेन में वर्गीकृत करने से अधिक तेज़ होना चाहिए । लेकिन TVP INSERTका 1 लेन-देन में 4000 s से अधिक के उपयोग से आने वाला लाभ उतने महत्वपूर्ण नहीं होगा जितना कि 800,000 अलग-अलग लेन-देन से 4000 पंक्तियों के प्रत्येक 200 लेन-देन पर जाने पर देखा गया सुधार।

    TVP विकल्प VBA पक्ष के लिए मूल रूप से उपलब्ध नहीं है, लेकिन कोई व्यक्ति ऐसे काम के साथ आया है, जो परीक्षण के लायक हो सकता है:

    VBA से SQL Server 2008 R2 में जाने पर मैं डेटाबेस प्रदर्शन को कैसे बेहतर करूँ?

  5. यदि फ़िल्टर खरीद केवल क्लॉज FileIDमें उपयोग की WHEREजा रही है, और यदि उस खरीद को वास्तव में प्रति पंक्ति कहा जा रहा है, तो आप पहले रन के परिणामों को कैशिंग करके और बाकी पंक्तियों के लिए उनका उपयोग करके कुछ प्रसंस्करण समय बचा सकते हैं FileID, सही?

  6. एक बार जब आप फाइलआईडी के अनुसार प्रसंस्करण कर लेते हैं , तो हम समानांतर प्रसंस्करण के बारे में बात करना शुरू कर सकते हैं। लेकिन उस बिंदु पर यह आवश्यक नहीं हो सकता है :)। यह देखते हुए कि आप 3 काफी प्रमुख गैर-आदर्श भागों के साथ काम कर रहे हैं: एक्सेल, VBA और 800k लेन-देन, SSIS, या समानांतर चतुर्भुज की कोई भी बात, या जो जानता है-क्या है, समय से पहले का अनुकूलन / कार्ट-से-हॉर्स सामान है । यदि हम इस 7 घंटे की प्रक्रिया को 10 मिनट या उससे कम समय तक प्राप्त कर सकते हैं, तो क्या आप इसे तेजी से बनाने के लिए अतिरिक्त तरीके सोच रहे हैं? क्या कोई लक्ष्य पूरा होने का समय है जो आपके मन में है? ध्यान रखें कि एक बार प्रसंस्करण प्रति FileID पर किया जाता है आधार, यदि आपके पास VB.NET कंसोल ऐप (यानी कमांड-लाइन .EXE) है, तो आपको एक बार में उन कुछ फ़ाइलआईडी को चलाने से कुछ नहीं होगा :), चाहे SQL एजेंट CmdExec चरण या विंडोज शेड्यूल किए गए मास्क के माध्यम से। आदि।

और, आप हमेशा "चरणबद्ध" दृष्टिकोण अपना सकते हैं और एक बार में कुछ सुधार कर सकते हैं। जैसे कि प्रति अपडेट करना शुरू करना FileIDऔर इसलिए उस समूह के लिए एक लेनदेन का उपयोग करना। फिर, देखें कि क्या आप टीवीपी काम कर सकते हैं। फिर उस कोड को लेने और इसे VB.NET में ले जाने के बारे में देखें (और TVPs .NET में काम करते हैं इसलिए यह अच्छी तरह से पोर्ट करेगा)।


क्या हम नहीं जानते कि अभी भी मदद कर सकता है:

  • क्या "फ़िल्टर" संग्रहीत कार्यविधि पंक्ति प्रति या फ़ाइल के अनुसार चलती है ? क्या हमारे पास उस संग्रहित प्रक्रिया की पूरी परिभाषा भी है?
  • तालिका का पूर्ण स्कीमा। यह तालिका कितनी चौड़ी है? चर की लंबाई के कितने क्षेत्र हैं? कितने क्षेत्र NULLable हैं? यदि कोई भी NULLable है, तो कितने NULLs हैं?
  • इस तालिका के लिए अनुक्रमणिका। क्या इसका विभाजन हुआ है? क्या ROW या PAGE कम्प्रेशन का उपयोग किया जा रहा है?
  • MB / GB के संदर्भ में यह तालिका कितनी बड़ी है?
  • इस तालिका के लिए सूचकांक रखरखाव कैसे संभाला जाता है? सूचकांक कितने खंडित हैं? आंकड़ों की तारीख कैसे अपडेट की जाती है?
  • क्या कोई अन्य प्रक्रिया इस तालिका को लिखती है जबकि यह 7 घंटे की प्रक्रिया हो रही है? विवाद का संभावित स्रोत।
  • क्या इस तालिका से कोई अन्य प्रक्रिया पढ़ी जाती है जबकि यह 7 घंटे की प्रक्रिया हो रही है? विवाद का संभावित स्रोत।

अद्यतन 1:

** VBA (विजुअल बेसिक फॉर एप्लिकेशन) और इसके साथ क्या किया जा सकता है, इस बारे में कुछ भ्रम प्रतीत होता है, इसलिए यह सुनिश्चित करने के लिए है कि हम सभी एक ही वेब-पेज पर हैं:


अद्यतन 2:

एक और बात पर विचार करें: कनेक्शन कैसे संभाले जा रहे हैं? क्या VBA कोड प्रत्येक ऑपरेशन के अनुसार कनेक्शन को खोलना और बंद करना है, या क्या यह प्रक्रिया की शुरुआत में कनेक्शन को खोलता है और प्रक्रिया के अंत में बंद कर देता है (अर्थात 7 घंटे बाद)? कनेक्शन पूलिंग के साथ भी (जो, डिफ़ॉल्ट रूप से, ADO के लिए सक्षम होना चाहिए), अभी भी खोलने और बंद करने के बीच काफी प्रभाव होना चाहिए, एक बार खोलने और बंद करने के विपरीत 800,200 या 1,600,000 बार। वे मान कम से कम 800,000 UPDATEs या तो 200 या 800k EXECs पर आधारित होते हैं (यह निर्भर करता है कि फ़िल्टर संग्रहीत प्रक्रिया वास्तव में कैसे निष्पादित की जा रही है)।

बहुत से कनेक्शन का यह मुद्दा स्वचालित रूप से ऊपर उल्लिखित सिफारिश से कम हो गया है। एक लेनदेन बनाकर और उस लेनदेन के भीतर सभी अद्यतन करने के बाद, आप उस कनेक्शन को खुला रखने वाले हैं और प्रत्येक के लिए पुन: उपयोग कर रहे हैं UPDATE। निर्दिष्ट FileIDया प्रति 4000 पंक्तियों को प्राप्त करने के लिए प्रारंभिक कॉल से कनेक्शन को खुला रखा गया है या नहीं , या उसके बाद बंद हो गया "ऑपरेशन" और फिर से UPDATEs के लिए खोला गया, अब तक कम प्रभाव है क्योंकि अब हम दोनों के अंतर के बारे में बात कर रहे हैं पूरी प्रक्रिया में 200 या 400 कुल कनेक्शन।

अद्यतन 3:

मैंने कुछ त्वरित परीक्षण किया। कृपया ध्यान रखें कि यह एक छोटे पैमाने पर परीक्षण है, और सटीक एक ही ऑपरेशन नहीं है (शुद्ध INSERT बनाम EXEC + UPDATE)। हालांकि, कनेक्शन और लेन-देन को कैसे संभाला जाता है, इससे संबंधित समय में अंतर अभी भी प्रासंगिक है, इसलिए यहां अपेक्षाकृत समान प्रभाव रखने के लिए जानकारी को एक्सट्रपलेशन किया जा सकता है।

परीक्षण पैरामीटर:

  • SQL सर्वर 2012 डेवलपर संस्करण (64-बिट), SP2
  • तालिका:

     CREATE TABLE dbo.ManyInserts
     (
        RowID INT NOT NULL IDENTITY(1, 1) PRIMARY KEY,
        InsertTime DATETIME NOT NULL DEFAULT (GETDATE()),
        SomeValue BIGINT NULL
     );
    
  • ऑपरेशन:

    INSERT INTO dbo.ManyInserts (SomeValue) VALUES ({LoopIndex * 12});
  • प्रत्येक परीक्षण में कुल आवेषण: 10,000
  • प्रत्येक परीक्षण के अनुसार रीसेट: TRUNCATE TABLE dbo.ManyInserts;(इस परीक्षण की प्रकृति को देखते हुए, FREEPROCCACHE, FREESYSTEMCACHE और DROPCLEANBUFFERS बहुत अधिक मूल्य नहीं जोड़ते हैं।)
  • रिकवरी मॉडल: SIMPLE (और लॉग फ़ाइल में शायद 1 जीबी मुफ्त)
  • लेनदेन का उपयोग करने वाले टेस्ट केवल एक ही कनेक्शन का उपयोग करते हैं, भले ही कितने लेनदेन हों।

परिणाम:

Test                                   Milliseconds
-------                                ------------
10k INSERTs across 10k Connections     3968 - 4163
10k INSERTs across 1 Connection        3466 - 3654
10k INSERTs across 1 Transaction       1074 - 1086
10k INSERTs across 10 Transactions     1095 - 1169

जैसा कि आप देख सकते हैं, भले ही डीबी के लिए एडीओ कनेक्शन पहले से ही सभी ऑपरेशनों में साझा किया जा रहा है, उन्हें एक स्पष्ट लेनदेन का उपयोग करके बैचों में समूहित करना (एडीओ ऑब्जेक्ट को इसे संभालने में सक्षम होना चाहिए) को महत्वपूर्ण रूप से गारंटी दी जाती है (यानी 2x सुधार पर) समग्र प्रक्रिया का समय कम करें।


Srutzky क्या सुझाव दे रहा है, इसके लिए एक अच्छा "मध्यम पुरुष" दृष्टिकोण है, और यह है कि आप SQL सर्वर से बाहर डेटा की जरूरत है, डेटा काम करने के लिए अपने VBA स्क्रिप्ट को कॉल करने के लिए PowerShell का उपयोग करें, और फिर SQL सर्वर में एक अद्यतन SP कॉल करें , चाबियाँ और अद्यतन मूल्यों को SQL सर्वर पर वापस भेजना। इस तरह आप एक सेट आधारित दृष्टिकोण को जोड़ते हैं जो आपके पास पहले से है।
स्टीव मैंगमेली

@SteveMangiameli हाय स्टीव और टिप्पणी के लिए धन्यवाद। मैंने जल्द ही जवाब दिया होगा, लेकिन बीमार हो गया है। मुझे उत्सुकता है कि मैं जो सुझाव दे रहा हूं, उससे आपका विचार कितना भिन्न है। सभी संकेत हैं कि एक्सेल को अभी भी VBA को चलाने की आवश्यकता है। या आप यह सुझाव दे रहे हैं कि PowerShell ADO की जगह लेगा, और यदि I / O में अधिक तेज़ होगा, तो क्या इसके लायक भी होगा यदि केवल I / O को प्रतिस्थापित किया जाए?
सोलोमन रटज़की

1
कोई चिंता नहीं, ख़ुशी आपकी भावना बेहतर है। मुझे नहीं पता कि यह बेहतर होगा। हम नहीं जानते कि हम क्या नहीं जानते हैं और आपने कुछ महान विश्लेषण किए हैं लेकिन फिर भी कुछ धारणाएं बनानी होंगी। I / O महत्वपूर्ण हो सकता है कि वह अपने आप को बदल सके; हमें अभी पता नहीं है। मैं सिर्फ एक और दृष्टिकोण प्रस्तुत करना चाहता था जो आपके द्वारा सुझाई गई चीजों के साथ सहायक हो सकता है।
स्टीव मैंगमेली

@SteveMangiameli धन्यवाद और स्पष्ट करने के लिए धन्यवाद। मुझे आपकी सटीक दिशा का यकीन नहीं था और यह लगा कि यह सबसे अच्छा नहीं है। हां, मैं मानता हूं कि अधिक विकल्प होना बेहतर है क्योंकि हम नहीं जानते कि क्या बदलाव किए जा सकते हैं और क्या बाधाएं हैं :)।
सोलोमन रटज़की

हे srutzky, विस्तृत विचारों के लिए धन्यवाद! मैं SQL साइड इंडेक्स और क्वेरीज़ को अनुकूलित कर रहा हूं और बाधाओं को खोजने की कोशिश कर रहा हूं। मैंने अब एक उचित सर्वर में निवेश किया है, 36cores, 1TB ने PCIe SSDs को छीन लिया क्योंकि IO नीचे चल रहा था। अब एसएसबी में सीधे वीबी कोड को कॉल करने पर जो समानांतर निष्पादन के लिए कई थ्रेड्स खोलता है।
मड़वार

2

IMHO और इस धारणा से कार्य करना कि VBA को SQL में फिर से कोड करना संभव नहीं है, क्या आपने VBA स्क्रिप्ट को एक्सेल फाइल में मूल्यांकन समाप्त करने की अनुमति दी है और फिर परिणाम SSIS के माध्यम से SQL सर्वर पर वापस लिखें?

आप VBA उप आरंभ और अंत एक फाइलसिस्टम ऑब्जेक्ट में या सर्वर में (यदि आपने पहले से ही सर्वर में वापस लिखने के लिए कनेक्शन कॉन्फ़िगर किया है) में एक संकेतक को फ़्लिप करने के साथ कर सकते हैं और फिर इस संकेतक की जांच करने के लिए SSIS अभिव्यक्ति का उपयोग कर सकते हैं। disableआपके SSIS समाधान के भीतर दिए गए कार्य की संपत्ति (ताकि आयात प्रक्रिया तब तक प्रतीक्षा करें जब तक कि VBA उप पूरा न हो जाए यदि आप इसके बारे में चिंतित हैं तो यह अपने शेड्यूल को ओवररलाइज़ करता है)।

इसके अतिरिक्त, आप VBA स्क्रिप्ट को प्रोग्रामेटिक रूप से शुरू कर सकते हैं (थोड़ा विस्की, लेकिन मैंने workbook_open()संपत्ति का उपयोग "आग लगाने और अतीत में इस प्रकृति के कार्यों को भूलने" के लिए किया है)।

यदि VB स्क्रिप्ट का मूल्यांकन समय एक मुद्दा बनने लगता है, तो आप देख सकते हैं कि क्या आपका VB डेवलपर SSIS समाधान के भीतर VB स्क्रिप्ट कार्य में अपने कोड को पोर्ट करने के लिए तैयार है और सक्षम है - मेरे अनुभव में एक्सेल एप्लिकेशन बहुत अधिक ओवरहेड खींचता है जब इस वॉल्यूम पर डेटा के साथ काम करना।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.