2009-06-22 8 views
9

में टक्कर (मुझे 6,651,744 पंक्तियों की एक तालिका मिली है, जिसमें 6 कॉलम (इंट x 3, छोटा, वर्चर (3 9), वर्कर (2) से बना प्राथमिक कुंजी है। मैं इस तालिका और अन्य तालिका के साथ प्रदर्शन में सुधार करना चाहता हूं जो इस प्राथमिक कुंजी को साझा करता है और अतिरिक्त कॉलम जोड़ता है लेकिन इसमें 37 मीटर पंक्तियां हैं।चेक सर्वर (एसक्यूएल सर्वर 2005

हैश कुंजी बनाने के लिए कॉलम जोड़ने की प्रत्याशा में, मैंने एक विश्लेषण किया और 18,733 टकराव पाए।

SELECT SUM(CT) 
FROM (
     SELECT HASH_KEY 
       ,COUNT(*) AS CT 
     FROM (
       SELECT CHECKSUM(DATA_DT_ID, BANK_NUM, COST_CTR_NUM, 
           GL_ACCT_NUM, ACCT_NUM, APPN_CD) AS HASH_KEY 
       FROM CUST_ACCT_PRFTBLT 
       ) AS X 
     GROUP BY HASH_KEY 
     HAVING COUNT(*) > 1 
     ) AS Y 

SELECT COUNT(*) 
FROM CUST_ACCT_PRFTBLT 

यह बारे में दो बार के रूप में बुरा BINARY_CHECKSUM()

इस बहुत अधिक (.33%) लगता है गंतव्य अंतरिक्ष मैं कवर कर रहा हूँ के छोटे रिश्तेदार अवधि दी गयी है साथ? और यदि टकराव इस उच्च हैं, तो क्या इस निर्मित कुंजी पर प्रति पंक्ति अतिरिक्त 4 बाइट्स की लागत के लिए पहली बार शामिल होने में शामिल होने का लाभ है, बशर्ते कि आपको कभी-कभी नियमित कॉलम पर कभी-कभी टक्कर संभालने के लिए शामिल होना पड़ेगा?

+0

आप एक बार में कितने रिकॉर्ड शामिल हो रहे हैं? क्या विस्तार तालिका में क्लस्टर्ड इंडेक्स है? कितना चौड़ा? यदि क्लस्टर सूचकांक व्यापक है (यानी, इसमें सभी एफके शामिल हैं), क्या आप इसे छोड़ सकते हैं या इसे पहचान कॉलम से बदल सकते हैं? –

+0

यह आपके लिए एक समस्या क्यों है? आपको पूरा करने की क्या ज़रूरत है? –

+0

समस्या यह है कि आंकड़ों की 37 मीटर पंक्तियों से उत्पन्न होने के लिए व्युत्पन्न आंकड़ों की 200 मीटर पंक्तियां हैं और गणना करने के लिए PIVOT को बहुत बड़ी कुंजी पर पिवोट करना पड़ता है जिसके परिणामस्वरूप tempdb में सभी 37m पंक्तियों का एक बुरा उत्सुक स्पूल होता है। –

उत्तर

7

मैं देख नहीं है, जहां एक checksum जोड़ने आप collisons के उस स्तर के साथ कुछ भी मिल जाएगा है। यहां तक ​​कि 1 टक्कर भी बहुत अधिक है क्योंकि इससे आपको गलत डेटा में शामिल होना पड़ेगा। यदि आप सही रिकॉर्ड में शामिल होने की गारंटी नहीं दे सकते हैं, तो यह निष्पक्ष है अगर यह प्रदर्शन में सुधार करता है लेकिन डेटा अखंडता के साथ गड़बड़ करता है। यह वित्तीय डेटा प्रतीत होता है, इसलिए आप वास्तव में यह सुनिश्चित कर सकते थे कि आपके प्रश्न खराब नतीजे वापस नहीं आएंगे। यदि कोई टक्कर हो तो आप वास्तव में गलत खातों को डेबिट या क्रेडिट कर सकते हैं।

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

क्या आपने सरोगेट कुंजी का उपयोग करने पर विचार किया है और फिर इसके बजाय छह प्राकृतिक कुंजी क्षेत्रों पर एक अद्वितीय अनुक्रमणिका है? फिर आप सरोगेट कुंजी पर शामिल हो सकते हैं और संभवतः प्रदर्शन में सुधार होगा। यह एक सरोगेट कुंजी के बजाय छह कॉलम (एक वर्चर) में शामिल होने के लिए सक्षम नहीं हो सकता है। मुझे डेटा के आकार से एहसास होता है, यह एक गैर-उत्पादन प्रणाली की तुलना में रिफैक्टर के लिए कठिन हो सकता है, लेकिन वास्तव में यह लगातार प्रदर्शन समस्याओं को स्थायी रूप से ठीक करने के लिए डाउन टाइम के लायक हो सकता है। केवल आप ही कह सकते हैं कि यह कितना जटिल होगा और बेहतर स्पष्टीकरण के लिए सभी एसपी या प्रश्नों को बदलने में कितना मुश्किल होगा। हालांकि, कोशिश करने के लिए संभव हो सकता है।

+0

मुझे सरगेट और सभी पीके कॉलम पर भी शामिल होना होगा। सरोगेट को इंडेक्स में पहला कॉलम होना चाहिए (जिसे ऑप्टिमाइज़र उम्मीदपूर्वक चुनता है), लेकिन सभी कॉलम में शामिल होना होगा। इस एमएसडीएन दस्तावेज में एक उदाहरण है (केवल एक खोज, शामिल नहीं है): http://msdn.microsoft.com/en-us/library/ms189788(SQL.90).aspx –

+0

क्यों शामिल होने की आवश्यकता होगी सरोगेट कुंजी और प्राकृतिक प्राथमिक कुंजी कॉलम? सरोगेट कुंजी को दोनों टेबलों में जोड़ा जाना होगा, लेकिन आप उस 6 फ़ील्ड के बजाय इसका उपयोग करेंगे जो आप वर्तमान में शामिल होने में उपयोग कर रहे हैं। – LanceSc

+0

मैं देखता हूं, सिर्फ एक हैश की बजाय एक असली अद्वितीय सरोगेट। खैर, दुर्भाग्य से, विरासत प्रणाली मैं पुन: इंजीनियरिंग में आरआई नहीं है, इसलिए वास्तव में 37 मीटर पंक्ति स्टेट तालिका में प्रविष्टियां हैं जिनके पास 5 मीटर पंक्ति पीके तालिका में कोई प्रविष्टि नहीं है। मुझे इस पर सोचना होगा। –

2

यदि आपका चेकसम डेटा के 0.33% तक पहुंच जाता है, तो मैं तर्क दूंगा कि यह ठीक काम कर रहा है ... विशेष रूप से यदि आप इस कॉलम को अन्य (अनुक्रमित) कॉलम के साथ संयोजन में उपयोग करते हैं।

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

बेशक

, प्रश्न में स्तंभों पर एक नियमित रूप से फैले सूचकांक बस के रूप में अच्छी तरह से या बेहतर कर सकते हैं ...

+0

हां, मैं एक सतत गणना वाले कॉलम का उपयोग करने की योजना बना रहा था। –

1

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

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

आप इंडेक्स की तलाश के लिए अनुकूलित करना चाहते हैं। चेकसम पहले से ही अत्यधिक चुनिंदा है। एफके जोड़ना इंडेक्स आकार और संबंधित I/O को बढ़ाएगा, और जब तक इसमें बुकमार्क लुकअप से बचने के लिए पर्याप्त अन्य फ़ील्ड शामिल नहीं होते हैं, तब तक मदद नहीं करेगा।

चूंकि गैर-क्लस्टर्ड इंडेक्स में क्लस्टरिंग कुंजी या ढेर पॉइंटर होगा, तो आप या तो एक चाहते हैं) एक छोटी क्लस्टरिंग कुंजी (उदाहरण के लिए, एक इंट पहचान कॉलम - 4 बाइट पॉइंटर) या बी) कोई क्लस्टर्ड इंडेक्स बिल्कुल नहीं (8 बाइट पॉइंटर)।

यदि आपके प्रश्न चुनिंदा नहीं हैं, या यदि लाइन टेबल क्लस्टर्ड इंडेक्स विशाल है (पूरी तालिका कुछ स्तंभों को घटाती है) तो मुझे नहीं पता कि चेकसम मदद करेगा (तेज सूचकांक नेविगेशन, शायद?)। किसी भी मामले में आप इसे क्लस्टर्ड या कवर इंडेक्स बनाना चाहते हैं, और यदि हेडर टेबल पहले चेकसम पर क्लस्टर नहीं किया गया है, तो बहुत अधिक सॉर्टिंग होगी।

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

1

यदि आपका PRIMARY KEY क्लस्टर किया गया है, तो आपके द्वारा बनाए गए प्रत्येक इंडेक्स में यह PRIMARY KEY होगा।

हैश मूल्य पर शामिल होने से इस निम्न चरणों का उपयोग होगा:

  • उपयोग Clustered Index Seek पता लगाने के लिए

    1. सूचकांक कुंजी में टुकड़ों में बंटी मान
      • सूचकांक डेटा में PRIMARY KEY मान PRIMARY KEY तालिका में पंक्ति

    PRIMARY KEY पर शामिल होने से केवल का उपयोग किया जाएगा।

    SQL Server, तथापि, बहुत चालाक खाते में लेने के लिए है, और अगर आप इस तरह शामिल हो जाएगा:

    SELECT * 
    FROM main_table mt 
    JOIN CUST_ACCT_PRFTBLT cap 
    ON  cap.HASH_KEY = mt.HASH_KEY 
         AND cap.DATA_DT_ID = mt.DATA_DT_ID 
         AND … 
    WHERE mt.some_col = @filter_value 
    

    , यह सिर्फ सूचकांक HASH_KEY पर उपयोग नहीं होगा, बजाय, यह एक एकल का उपयोग करेगा हैश मान मिलान (और वे हमेशा करेंगे) सुनिश्चित करने के लिए Clustered Index Seek और Filter

    सारांश: बस PRIMARY KEY पर शामिल हों।

    द्वितीयक अनुक्रमणिका का उपयोग करके, आपको पहले बेकार HASH_KEY खोज करने की आवश्यकता होगी, और फिर भी PRIMARY KEY पर शामिल होने की आवश्यकता है।

  • +0

    हां, मैंने इस पुन: इंजीनियरिंग के दौरान इस प्रक्रिया के पुनर्गठन से बहुत अधिक बचाव किया है, लेकिन क्योंकि पीके इतना व्यापक (और क्लस्टर) है, मुझे लगता है कि मैं इसे निकाल सकता हूं और इसके बजाय सरोगेट का उपयोग कर सकता हूं। इस मामले में, हैश अप्रासंगिक है। मेरी मुख्य समस्या यह है कि CUST_ACCT_STAT में पंक्तियां समाप्त होती हैं जिनके पास मूल सिस्टम में खराब आरआई के कारण CUST_ACCT_PRFTBLT में कोई मिलान नहीं है, इसलिए मुझे उन लोगों के लिए पंक्तियों का अनुमान लगाने की आवश्यकता होगी। –

    6

    मैंने अब तक बहुत से लोगों को चमकते हुए देखा है कि CHECKSUM में Microsoft's own admission द्वारा टकराव का एक टन है। यह MD5 से भी बदतर है, जिसका सार्थक टकराव का उचित हिस्सा है।

    यदि आप हैश कॉलम प्राप्त करना चाहते हैं, तो का उपयोग SHA1 के साथ निर्दिष्ट करने पर विचार करें। SHA1 में MD5 या CHECKSUM से बहुत कम अर्थपूर्ण टकराव हैं। इसलिए, CHECKSUM का उपयोग यह निर्धारित करने के लिए कभी नहीं किया जाना चाहिए कि कोई पंक्ति अद्वितीय है या नहीं, बल्कि, यह दो मानों की निष्ठा पर त्वरित जांच है।इसलिए, आपकी टकराव दर HASHBYTES के साथ 0% होनी चाहिए, जब तक आपके पास डुप्लिकेट पंक्तियां नहीं होतीं (जो, पीके होने पर, कभी नहीं होना चाहिए)।

    ध्यान रखें कि HASHBYTES 8000 बाइट से बड़ा कुछ भी छोटा कर देगा, लेकिन आपका पीके उस से बहुत कम है (सभी समेकित), इसलिए आपको कोई परेशानी नहीं होनी चाहिए।

    +1

    मैंने स्कीमा को एक आयाम तालिका में एक वास्तविक अद्वितीय सरोगेट का उपयोग करने के लिए दोबारा प्रतिक्रिया दी है और इसे तीन तालिकाओं की प्राथमिक कुंजी बना दिया है। प्रदर्शन में काफी सुधार हुआ है। –