एक डेटाबेस में सभी तालिकाओं के असम्पीडित आकार का पता लगाएं


12

डायनेमिक्स AX में एक कैशिंग मैकेनिज्म होता है जहां टेबल को मेमोरी और कैश्ड में लोड करने के लिए कॉन्फ़िगर किया जा सकता है। यह कैश स्मृति समस्याओं को रोकने के लिए KB की एक निश्चित राशि तक सीमित है। मैं जिस सेटिंग के बारे में बात कर रहा हूं उसे कॉल किया जाता है entiretablecacheऔर जैसे ही एक एकल रिकॉर्ड का अनुरोध किया जाता है , पूरे टेबल को मेमोरी में लोड कर देता है।

हाल ही में हमने टेबल के आकार को सत्यापित करने के लिए कुछ लिपियों पर भरोसा किया, जिसमें यह देखने के लिए सेटिंग है कि क्या टेबल का आकार इस सीमा से ऊपर है।

अब हालांकि, संपीड़न खेल में आता है और sp_spaceused या sys.allocation_units जैसी चीजें वास्तव में संपीड़ित डेटा द्वारा उपयोग किए जाने वाले स्थान की रिपोर्ट करती हैं।

जाहिर है, एप्लिकेशन सर्वर असम्पीडित डेटा के साथ काम कर रहा है, इसलिए SQL सर्वर में डिस्क पर डेटा का आकार अप्रासंगिक है। मैं वास्तविक आकार की जरूरत है असम्पीडित डेटा होगा।

मुझे sp_estimate_data_compression_savings के बारे में पता है लेकिन जैसा कि नाम कहता है, यह सिर्फ एक अनुमान है।
मैं जितना संभव हो उतना सही आकार लेना पसंद करूंगा।

जिस तरह से मैं सोच सकता था कि कुछ जटिल गतिशील एसक्यूएल एक ही संरचना के साथ असम्पीडित तालिकाओं के रूप में बना रहा था, जो उस छाया तालिका में संपीड़ित डेटा सम्मिलित करता है और फिर उस छाया तालिका के आकार की जांच करता है।
कहने की जरूरत नहीं है, यह थोड़ा थकाऊ है और कई सैकड़ों जीबी के डेटाबेस पर चलने में थोड़ा समय लगता है।

पॉवर्सशेल एक विकल्प हो सकता है, लेकिन मैं select *स्क्रिप्ट पर आकार की जांच करने के लिए उन पर प्रदर्शन करने के लिए सभी तालिकाओं पर पुनरावृति नहीं करना चाहूंगा क्योंकि यह कैश को बाढ़ देगा और शायद बहुत लंबा समय लगेगा।

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

मान लें कि एप्लिकेशन में बफर डेटा का आकार है। एक Bigint हमेशा एक bigint का आकार होता है, और एक वर्ण डेटा प्रकार 2 बाइट्स प्रति वर्ण (यूनिकोड) होता है। BLOB डेटा डेटा का आकार भी लेता है, एक एनम मूल रूप से एक int है और संख्यात्मक डेटा संख्यात्मक (38,12) है, डेटाटाइम एक डेटाइम का आकार है। इसके अलावा, कोई NULLमूल्य नहीं हैं, वे या तो एक खाली स्ट्रिंग, 1900-01-01या शून्य के रूप में संग्रहीत होते हैं ।

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

बड़ी टेबलों के लिए EntireTable कैश का उपयोग करने से बचें (AX 2009 में 128 KB या 16 पृष्ठों पर, AX 2012 में 'संपूर्ण तालिका कैश आकार' अनुप्रयोग सेटिंग पर [डिफ़ॉल्ट: 32KB, या 4 पृष्ठ]) - बजाय कैशिंग रिकॉर्ड करने के लिए।


3
यह हैकरी है, लेकिन सम्पीडन अक्षम के साथ शायद एक बहाल प्रति सबसे सटीक होगी। फिर आप रिस्टोर का भी परीक्षण कर रहे हैं, जो आपको एक टॉप 1 डीबीए की तरह दिखता है।
— एरिक डार्लिंग

विश्वास है कि आपका सबसे अच्छा दांव होगा। वहाँ तरह तरह की कोशिश करो और गणित कर सकते हैं। परिभाषित स्तंभ स्तंभ प्रकार और लंबाई से कितनी पंक्तियाँ गुणा की जाती हैं, फिर अनुक्रमणिका में जोड़ते हैं, आदि यह एक बहुत अधिक काम है जो बहाल करने और अपंगता को अक्षम करने की तुलना में @sp_BlitzErik ऊपर सुझाता है। और कौन टॉप 1 डीबीए नहीं बनना चाहेगा?
— माइक वाल्श

सभी स्तंभों के लिए SUM (datalength ()) असम्पीडित डेटा आकार प्राप्त करते हैं?
— तपका उआ

@sp_BlitzErik टिप्पणी के बजाय एक उत्तर हो सकता है।
— टॉम वी -

जवाबों:


7

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

जबकि इस जानकारी की इच्छा निश्चित रूप से समझने योग्य है, यह जानकारी प्राप्त करना, विशेष रूप से "सही संभव के रूप में" के संदर्भ में, सभी की तुलना में मुश्किल है, जो गलत धारणाओं के कारण उम्मीद कर रहा है। चाहे प्रश्न में उल्लिखित असम्पीडित छाया तालिका विचार हो, या @ sp_BlitzErik का सुझाव डीबी को बहाल करने और जाँच करने के लिए वहाँ असंवेदनशील है, यह नहीं माना जाना चाहिए कि असम्पीडित तालिका का आकार == स्मृति में उक्त डेटा का आकार एप्लिकेशन सर्वर पर:

  1. क्या तालिका में सभी पंक्तियों को कैश किया जा रहा है? या सिर्फ एक सीमा के भीतर? धारणा यहाँ यह सब है, और कहा कि सही हो सकता है, लेकिन मैं समझ यह कम से कम उल्लेखनीय है कि इस शक्ति मामला नहीं होना (जब तक प्रलेखन अन्यथा, लेकिन यह एक छोटी सी बात वैसे भी है, बस नहीं करना चाहता था इसका उल्लेख नहीं है)।

    प्रश्न को अद्यतन करने के लिए कहा गया था: हाँ, सभी पंक्तियों को कैश किया जा रहा है।

  2. संरचना ओवरहेड

    1. डीबी पक्ष पर:
      पृष्ठ और डीबी पक्ष पर पंक्ति-ओवरहेड : पृष्ठ पर कितनी पंक्तियाँ फिट होती हैं, यह कई कारकों द्वारा निर्धारित किया जाता है जो अनुमान लगा सकते हैं। यहां तक ​​कि FILLFACTOR100 (या 0) के साथ, पेज पर अभी भी कुछ अप्रयुक्त स्थान होने की संभावना है, क्योंकि यह पूरी पंक्ति के लिए पर्याप्त नहीं है। और वह पेज हेडर के अतिरिक्त है। इसके अलावा, यदि कोई स्नैपशॉट अलगाव क्रिया सक्षम है, तो मुझे विश्वास होगा कि संस्करण संख्या द्वारा प्रति पंक्ति में एक अतिरिक्त 13 बाइट्स, और जो अनुमानों को फेंक देगा। पंक्ति के वास्तविक आकार (NULL बिटमैप, वैरिएबल लेंथ कॉलम, आदि) से संबंधित अन्य मिनुटिया है, लेकिन इस प्रकार अब तक उल्लिखित आइटम अकेले बिंदु बनाना चाहिए।
    2. एप्लिकेशन सर्वर की ओर:
      कैश्ड परिणामों को संग्रहीत करने के लिए किस प्रकार के संग्रह का उपयोग किया जा रहा है? मुझे लगता है कि यह एक .NET ऐप है, तो क्या यह एक है DataTable? एक सामान्य सूची? एक छंटनी? प्रत्येक प्रकार के संग्रह में एक अलग मात्रा में सुनाई देती है। मैं किसी भी विकल्प की अपेक्षा नहीं करना चाहूंगा कि पृष्ठ और पंक्ति को डीबी साइड पर ओवरहेड किया जाए, विशेष रूप से बड़े पैमाने पर (मुझे यकीन है कि थोड़ी मात्रा में पंक्ति में विभिन्न पदार्थ नहीं हो सकते हैं, लेकिन आप मतभेदों की तलाश में नहीं हैं सैकड़ों बाइट्स या सिर्फ कुछ kB में)।
  3. जानकारी का प्रकार
    1. DB की तरफ:
      CHAR/ VARCHARडेटा को 1 बाइट प्रति वर्ण (क्षण के लिए डबल-बाइट वर्णों की अनदेखी) में संग्रहीत किया जाता है। XMLपाठ प्रतिनिधित्व के रूप में लगभग स्थान के रूप में ज्यादा जगह नहीं लेने के लिए अनुकूलित है। यह डेटाटाइप तत्व और विशेषता नामों का एक शब्दकोश बनाता है और दस्तावेज़ में उनके संबंधित आईडी (वास्तव में अच्छा, वास्तव में) के साथ उनके वास्तविक संदर्भों को बदलता है। अन्यथा, स्ट्रिंग मान सभी UTF-16 ("चरित्र" प्रति 2 या 4 बाइट्स हैं), जैसे NCHAR/ NVARCHAR। DATETIME26 और 8 बाइट्स के बीच है। DECIMAL5 और 17 बाइट्स (सटीक के आधार पर) के बीच है।
    2. एप्लिकेशन सर्वर की तरफ:
      स्ट्रिंग्स (फिर, .NET मानकर) हमेशा UTF-16 हैं। 8-बिट स्ट्रिंग्स के लिए कोई अनुकूलन नहीं है जैसे कि क्या VARCHARधारण करता है। लेकिन, स्ट्रिंग्स को "नजरबंद" भी किया जा सकता है जो एक साझा प्रति है जिसे कई बार संदर्भित किया जा सकता है (लेकिन मुझे नहीं पता कि यह संग्रह में तार के लिए काम करता है, या यदि ऐसा है, तो यह सभी प्रकार के संग्रह के लिए काम करता है)। XMLस्मृति में उसी तरह संग्रहीत किया जा सकता है या नहीं किया जा सकता है (मुझे यह देखना होगा)। DateTimeहमेशा 8 बाइट (T-SQL की तरह है DATETIME, लेकिन नहीं की तरह DATE, TIMEया DATETIME2)। Decimalहै हमेशा 16 बाइट्स ।

कहने के लिए यह सब: वहाँ बहुत कुछ भी नहीं है आप डीबी पक्ष पर कर सकते हैं ऐप सर्वर की तरफ भी काफी सटीक स्मृति पदचिह्न आकार है। आपको किसी विशेष तालिका के साथ लोड होने के बाद, ऐप सर्वर को स्वयं से पूछताछ करने का एक तरीका खोजने की आवश्यकता है, इसलिए पता है कि यह कितना बड़ा है। और मुझे यकीन नहीं है कि अगर कोई डिबगर आपको भरे हुए संग्रह के रनटाइम आकार को देखने देगा। यदि नहीं, तो पास होने का एकमात्र तरीका एक तालिका की सभी पंक्तियों के माध्यम से जाना होगा, प्रत्येक स्तंभ को उचित .NET आकार (जैसे INT= * 4, VARCHAR= DATALENGTH() * 2, NVARCHAR= DATALENGTH(), XML= 🙃, आदि) से गुणा करना होगा, लेकिन फिर भी यह प्रश्न छोड़ देता है संग्रह के ओवरहेड प्लस संग्रह के प्रत्येक तत्व।

प्रश्न में कुछ नई परिभाषा को देखते हुए, कोई संभवतः निम्न क्वेरी को बंद कर सकता है। और इससे कोई फर्क नहीं पड़ता कि तालिका संकुचित है या नहीं, हालांकि यह निर्धारित करना प्रत्येक व्यक्ति के लिए है कि क्या सभी पंक्तियों को स्कैन करना उत्पादन पर उचित है (शायद एक पुनर्स्थापना से या ऑफ-पीक घंटों के दौरान):

SELECT
   SUM( DATALENGTH([NVarcharColumn_1]) + DATALENGTH([NVarcharColumn_N]) ) + 
   SUM( (DATALENGTH([VarcharColumn_1]) + DATALENGTH([VarcharColumn_N])) * 2 ) + 
   SUM(4 * [number_of_INT_columns]) +
   SUM(8 * [number_of_BIGINT_and_DATETIME_columns]) +
   SUM(16 * [number_of_DECIMAL/NUMERIC_and_UNIQUEIDENTIFIER_columns]) +
   etc..
FROM [SchemaName].[TableName] WITH (NOLOCK) -- assuming no Snapshot Isolation

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


हमने बफ़र के आकार को सुनिश्चित करने के लिए कोड में चेक को लागू करना समाप्त कर दिया क्योंकि यह आवेदन के लिए प्रस्तुत किया गया है।
— टॉम वी -

6

आपके प्रश्न से ऐसा लगता है जैसे आपके पास अधिकतम कैश आकार है Sऔर आप उस आकार से अधिक कैश में तालिकाओं को लोड नहीं करना चाहते हैं। अगर यह सच है तो आपको प्रत्येक तालिका का सही आकार जानने की आवश्यकता नहीं है। आपको बस यह जानना होगा कि कोई तालिका अधिकतम कैश आकार से बड़ी या छोटी है या नहीं S। यह आपके टेबल की कॉलम परिभाषा और पंक्ति गणना के आधार पर एक काफी आसान समस्या है।

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

यदि आपके पास डेटा प्रकारों की मैपिंग कैश आकार के लिए है, तो आपको उन डेटा को देखे बिना भी कुछ तालिकाओं का मूल्यांकन करने में सक्षम होना चाहिए:

  1. यदि किसी तालिका में केवल स्थैतिक डेटा प्रकार (कोई तार या बूँदें नहीं) हैं, तो आप sys.partitionsस्तंभ परिभाषाओं का उपयोग करके तालिका की पंक्तियों की संख्या को देख सकते हैं और गणना कर सकते हैं।
  2. यदि बहुत सी पंक्तियों वाली तालिका में पर्याप्त स्थिर डेटा प्रकार के कॉलम हैं, तो आप इसके डेटा को देखे बिना इसे बहुत बड़े रूप में समाप्त करने में सक्षम हो सकते हैं। उदाहरण के लिए, 10 मिलियन पंक्तियों और 5 BIGINTस्तंभों वाली एक तालिका में उस डेटा का आकार 10000000 * (8 + 8 + 8 + 8 + 8) = 400 M बाइट्स हो सकता है जो आपकी कैश आकार सीमा से बड़ा हो सकता है S। इससे कोई फर्क नहीं पड़ता कि इसमें स्ट्रिंग कॉलम का एक गुच्छा है।
  3. यदि कुछ पंक्तियों वाली तालिका काफी छोटी है, तो आप यह पुष्टि करने में सक्षम हो सकते हैं कि यह सीमा से नीचे है यह मानकर कि प्रत्येक गतिशील डेटा प्रकार में अधिकतम संभव आकार है। उदाहरण के लिए, एक BIGINTस्तंभ और एक NVARCHAR(20)स्तंभ के साथ एक 100 पंक्ति तालिका 100 * (8 + 2 * 20) = 4800 बाइट्स से अधिक नहीं हो सकती है।
  4. यह सच हो सकता है कि यदि किसी तालिका में SQL सर्वर में एक संपीड़ित आकार होता है Sजो कि कुछ कारक से बड़ा होता है तो यह कैश में फिट होने की संभावना नहीं है। यदि ऐसा मान मौजूद है तो आपको यह पता लगाने के लिए परीक्षण करना होगा।
  5. आप इसमें भाग्यशाली हो सकते हैं कि सभी गतिशील कॉलम उन पर आंकड़े रखते हैं। सांख्यिकी में औसत लंबाई के बारे में जानकारी होती है और यह आपके उद्देश्यों के लिए पर्याप्त सटीक हो सकती है।

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

तालिका डेटा को तेज़ी से देखने वाले प्रश्नों को बनाने के लिए यहां कुछ विचार दिए गए हैं:

  1. बड़ी तालिकाओं के लिए आप TABLESAMPLEतब तक उपयोग करने में सक्षम हो सकते हैं जब तक कि आपका नमूना आकार काफी बड़ा हो।
  2. एक गुच्छेदार कुंजी के साथ बड़े तालिकाओं के लिए यह संकुल कुंजी पर बैचों में उन्हें संसाधित करने के लिए उपयोगी हो सकता है। दुर्भाग्य से मुझे SUM()उस एग्रीगेट के मान के आधार पर जल्दी क्विट करने के तरीके का पता नहीं है । मैंने केवल यही देखा है कि किस काम के लिए ROW_NUMBER()। लेकिन आप तालिका के पहले 10% को स्कैन कर सकते हैं, गणना किए गए डेटा आकार को बचा सकते हैं, अगले 10% को स्कैन कर सकते हैं, और इसी तरह। उन तालिकाओं के लिए जो कैश के लिए बहुत बड़ी हैं, आप जल्दी छोड़ने के लिए इस दृष्टिकोण के साथ काम की एक महत्वपूर्ण राशि को बचाने में सक्षम हो सकते हैं।
  3. कुछ तालिकाओं के लिए आप सभी भाग्यशाली हो सकते हैं, जिनमें सभी गतिशील स्तंभों पर अनुक्रमणिकाएं हों। पंक्ति के आकार या एक समय में प्रत्येक सूचकांक को स्कैन करने वाले अन्य कारकों के आधार पर टेबल स्कैन करने की तुलना में तेज हो सकता है। यदि आप किसी एकल स्तंभ पर अनुक्रमणिका पढ़ने के बाद तालिका का आकार बहुत बड़ा है तो आप इस प्रक्रिया को जल्दी छोड़ सकते हैं।
  4. हो सकता है कि आपके डायनेमिक कॉलम की औसत लंबाई समय के साथ बहुत अधिक न बदल रही हो। आपके द्वारा गणना की जाने वाली औसत लंबाई और थोड़ी देर के लिए अपनी गणना में उन मूल्यों का उपयोग करने से बचाना व्यावहारिक हो सकता है। आप तालिकाओं में डीएमएल गतिविधि के आधार पर या कुछ अन्य मीट्रिक के आधार पर इन मूल्यों को रीसेट कर सकते हैं।
  5. यदि एल्गोरिथम विकसित करने के लिए सभी तालिकाओं पर परीक्षण चलाना संभव है तो आप डेटा में पैटर्न का लाभ उठाने में सक्षम हो सकते हैं। उदाहरण के लिए, यदि आप पहले छोटी से शुरू होने वाली तालिकाओं को संसाधित करते हैं, तो आप यह जान सकते हैं कि एक बार जब आप 10 (मैंने इस नंबर को बना दिया) तालिकाओं को एक पंक्ति में रखते हैं जो कि कैश के लिए बहुत बड़ी हैं, तो यह बहुत संभावना नहीं है कि कोई भी बड़ी तालिका फिट होगी। कैश। यह स्वीकार्य हो सकता है अगर यह कुछ तालिकाओं को बाहर करने के लिए ठीक है जो संभवतः कैश में फिट हो सकते हैं।

मुझे एहसास है कि मैंने इस जवाब में कोई SQL कोड शामिल नहीं किया है। मुझे बताएं कि क्या उन विचारों के लिए डेमो कोड लिखना उपयोगी होगा जो मैंने यहां चर्चा की थी।


2
मैंने इस तरह की तालिकाओं को बाहर करने के दृष्टिकोण के बारे में नहीं सोचा था, मुझे दृष्टिकोण पसंद है
— टॉम वी -
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.