लाखों रिकॉर्ड के साथ एक तालिका को अपडेट करना, इसके 4 दिन हो गए हैं


12

मैं वर्तमान में लाखों रिकॉर्ड के साथ एक तालिका को अपडेट कर रहा हूं, इसके 4 दिन हो गए हैं और क्वेरी अभी भी निष्पादित हो रही है।

मैंने गतिविधि की जाँच की कि इसके शो चल रहे हैं कि क्वेरी चल रही है।

इवेंट लॉग में कोई त्रुटि नहीं है।

प्रदर्शन वार:

  • Tempdb डिस्क A (850 gb मुक्त स्थान) में
  • डिस्क बी में डेटाबेस फ़ाइल (750 जीबी मुक्त स्थान)
  • 16 जीबी रैम

कृपया मुझे सुझाव दें कि मुझे क्या करना चाहिए?

पूछताछ

UPDATE
    dbo.table1
SET 
    costPercentage = ISNULL(t2.PaymentIndex, 1.0),
    t2.TopUp_Amt = (ISNULL(t2.PaymentIndex, 1.0) - 1.0)
    * ISNULL(dbo.table1.Initial_Tariff_Amt, 0.00),
    Total_Tariff_Inc_t2 = ISNULL(t2.PaymentIndex, 1.0)
    * ISNULL(dbo.table1.Initial_Tariff_Amt, 0.00)
FROM
    dbo.table2 t2
WHERE
    LEFT(dbo.test1.procodet, 3) = LEFT(t2.ProviderCode, 3) COLLATE database_default 

जवाबों:


3

इस क्वेरी का एक दिलचस्प विवरण है जो मैंने पहले नहीं देखा था। फैब्रियो एरुजो के जवाब के लिए धन्यवाद अब मैं इसे देखता हूं: आप दो तालिकाओं तक पहुंच रहे हैं। मैंने पहले कभी अपडेट स्टेटमेंट के इस तरह के उपयोग को नहीं देखा है और मैं इसका उपयोग करने की सलाह नहीं देता। मेरा सुझाव है कि आप फैब्रिकियो के उत्तर के प्रति अधिक सहज जुड़ने वाले वाक्यविन्यास का उपयोग करें।

संभावित कारण यह है कि दो तालिकाओं के बीच जुड़ने से अत्यधिक संख्या में पंक्तियों का निर्माण होता है। यदि LEFT(col, 3)अभिव्यक्ति डुप्लिकेट मान उत्पन्न करता है तो ऐसा हो सकता है । यदि यह 10 डुप्लिकेट का उत्पादन करता है तो यह परिणाम में 100000x100000 = 10000000000 पंक्तियों में शामिल हो जाएगा।

मुझे नहीं लगता कि इंडेक्सिंग यहां कोई भूमिका निभाता है। SQL सर्वर हैश या मर्ज जॉइन के साथ इस unindexed join को ठीक हल कर सकता है। 4 दिन नहीं लगते।

संभवतया अन्य कारण जुड़ने वाले इनपुट या आउटपुट के कार्डिनैलिटी को कम आंकना होगा। SQL सर्वर ने लूप जॉइन को चुना होगा।

जैसा कि यह अभी भी अटकलें है कि मैं सुझाव देता हूं कि आप क्वेरी योजना पोस्ट करें जो इस मुद्दे पर प्रकाश डालेगी।


8

इस क्वेरी के लिए आपको तालिका की प्रत्येक पंक्ति को स्कैन करना होगा क्योंकि

  • मुझे लगता है कि प्रोकोड या प्रोवाइडरकोड इंडेक्स नहीं हैं
  • यहां तक ​​कि अगर उन्हें अनुक्रमित किया गया था, तो आपके पास एक LEFT है जो WHERE पर समर्पित है
  • और आपके पास COLLATE भी है जो प्रभावी रूप से WHERE पर समर्पित कार्य है

"WHERE विधेय पर एक फ़ंक्शन" का अर्थ है कि अनुक्रमित का उपयोग नहीं किया जाएगा

यदि आप इसे बैच करते हैं (UPDATE TOP (10000) पर कहें ... और costPercentage IS NULL) तो आपको costPercentage पर एक इंडेक्स चाहिए और यह मान लें कि आप इसे सेट कर रहे हैं।

एकमात्र समाधान जो मैं देख रहा हूं

  • प्राथमिक कुंजी के आधार पर, बैचों में एक नई तालिका बनाएं
  • LEFT और COLLATE अभिव्यक्तियों को छिपाने के लिए अनुक्रमित, गणना किए गए कॉलम बनाएं, फिर अपडेट चलाएं

@ gbn .. धन्यवाद यह एक महान विचार है .. लेकिन जैसा कि डेटा लाखों में है इस प्रक्रिया में समय लगेगा .... मैं सोच रहा था कि क्वेरी की प्रगति का पता लगाने का एक तरीका हो सकता है?
लकी

1
पंक्तियों के "लाखों" स्कैन करने में 4 दिन क्यों लगेंगे? कोई फर्क नहीं पड़ता कि पंक्तियों को कितना बड़ा और भारी अनुक्रमित किया जा सकता है, जिसमें 4 दिन नहीं लगने चाहिए। समस्या की जड़ अभी भी अज्ञात है।
usr

1
यदि आप बड़े डेटा के साथ नियमित रूप से व्यवहार करते हैं, तो आपके बारे में उसके लिए एक उचित सर्वर क्या है? डेटा को SSD आदि पर रखें
टॉमटॉम

1
@ अच्छा यकीन है। मैं जवाब को संबोधित कर रहा था। कुछ गड़बड़ है जो हमें अभी तक नहीं मिली है। यह स्वयं या हार्डवेयर द्वारा क्वेरी नहीं है। यह 4 दिनों की अवधि के लिए राशि नहीं होगी।
usr

3
यह देखते हुए कि क्वेरी स्तंभ के 3 वर्ण भाग को किसी अन्य स्तंभ के 3 वर्ण भाग में शामिल कर रही है, परिणाम की संभावना डुप्लिकेट से अधिक होगी। यह केवल लाखों पंक्तियों को अपडेट करने की तुलना में बहुत खराब है। मुझे यकीन है कि यह अरबों में एक कार्य तालिका के माध्यम से स्कैन कर रहा है।
डेटागोड

4

सबसे पहले, क्वेरी को इसमें बदलें:

UPDATE t1
SET 
    costPercentage = ISNULL(t2.PaymentIndex, 1.0),
    t2.TopUp_Amt = (ISNULL(t2.PaymentIndex, 1.0) - 1.0)
    * ISNULL(dbo.table1.Initial_Tariff_Amt, 0.00),
    Total_Tariff_Inc_t2 = ISNULL(t2.PaymentIndex, 1.0)
    * ISNULL(dbo.table1.Initial_Tariff_Amt, 0.00)
FROM
  dbo.table1 t1
  inner join dbo.table2 t2
    on LEFT(t1.procodet, 3) = LEFT(t2.ProviderCode, 3) COLLATE database_default 

उस चर्चा में जेफ मोदेन की पहली पोस्ट के अनुसार , आपकी क्वेरी "हेलोवीन प्रभाव" के बारे में चेतावनी देने वाले के समान है।

उसके बाद, उन LEFT अभिव्यक्तियों को अनुक्रमित किया जाना चाहिए। gbn का उत्तर आपको यह करने का संकेत देता है कि यह कैसे करना है।

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