तालिका का डेटा स्थान कच्चे डेटा का आकार 4 गुना क्यों हो सकता है?


18

मेरे पास एक तालिका है जिसमें 490 M पंक्तियाँ और 55 GB तालिका स्थान है, इसलिए प्रति पंक्ति लगभग 167 बाइट्स हैं। तालिका में तीन कॉलम हैं: VARCHAR(100)DATETIME2(0), और ए SMALLINTVARCHARक्षेत्र में पाठ की औसत लंबाई लगभग 21.5 है, इसलिए कच्चे डेटा को लगभग 32 बाइट प्रति पंक्ति: 22 + 2 के लिए VARCHAR, 6 के लिए 6 DATETIME2, और 16-बिट पूर्णांक के लिए 2 होना चाहिए ।

ध्यान दें कि ऊपर दिया गया स्थान केवल डेटा है, सूचक नहीं। मैं गुणों के तहत बताए गए मूल्य का उपयोग कर रहा हूँ | भंडारण | सामान्य | डेटा स्थान।

बेशक कुछ ओवरहेड होना चाहिए , लेकिन प्रति पंक्ति 135 बाइट्स बहुत कुछ की तरह लगता है, खासकर एक बड़ी तालिका के लिए। ऐसा क्यों हो सकता है? क्या किसी और के समान गुणक देखे गए हैं? क्या कारक आवश्यक अतिरिक्त स्थान की मात्रा को प्रभावित कर सकते हैं?

तुलना के लिए, मैंने दो INTफ़ील्ड और 1 M पंक्तियों के साथ एक तालिका बनाने का प्रयास किया । कच्चे डेटा के 8 बाइट्स की तुलना में आवश्यक डेटा स्पेस 16.4 एमबी: 17 बाइट्स प्रति पंक्ति था। एक और टेस्ट के साथ एक INTऔर टेबुल, जिसमें एक VARCHAR(100)ही टेक्स्ट होता है, असली टेबल 39 बाइट्स प्रति पंक्ति (44 K पंक्तियों) का उपयोग करती है, जहाँ मुझे 28 प्लस थोड़ी उम्मीद होती है।

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

किसी भी संकेत के लिए अग्रिम धन्यवाद!

संपादित करें:

सूचीबद्ध सभी फ़ील्ड हैं NOT NULL। वास्तविक तालिका में उस क्रम में VARCHARफ़ील्ड और फ़ील्ड पर एक संकुल PK है DATETIME2। दो परीक्षणों के लिए, पहला INT(क्लस्टर) पीके था।

यदि यह मायने रखता है: तालिका पिंग परिणामों का रिकॉर्ड है। फ़ील्ड URL, पिंग दिनांक / समय और मिलीसेकंड में विलंबता हैं। डेटा को लगातार जोड़ा जाता है, और कभी भी अपडेट नहीं किया जाता है, लेकिन डेटा को समय-समय पर हटाकर इसे प्रति URL प्रति घंटे केवल कुछ रिकॉर्ड तक काट दिया जाता है।

संपादित करें:

एक बहुत ही दिलचस्प जवाब यहाँ है कि पता चलता है, बहुत पढ़ने और लिखने के साथ एक सूचकांक के लिए, पुनर्निर्माण नहीं फायदेमंद हो सकता है। मेरे मामले में, खपत की जाने वाली जगह एक चिंता का विषय है, लेकिन अगर लेखन प्रदर्शन अधिक महत्वपूर्ण है, तो व्यक्ति भड़कीले सूचकांकों के साथ बेहतर हो सकता है।

जवाबों:


11

मूल प्रश्न पर टिप्पणियों में चर्चा के बाद, यह इस मामले में प्रकट होता है कि खोई हुई जगह क्लस्टर कुंजी की पसंद के कारण होती है, जिसके कारण बड़े पैमाने पर विखंडन हुआ है।

हमेशा इन स्थितियों में sysinos_db_index_physical_stats के माध्यम से विखंडन की स्थिति की जांच करने के लायक है।

संपादित करें: टिप्पणियों में अपडेट के बाद

औसत पृष्ठ घनत्व (क्लस्टर इंडेक्स के पुनर्निर्माण से पहले) 24% था, जो मूल प्रश्न के साथ पूरी तरह फिट बैठता है। पृष्ठ केवल 1/4 भरे हुए थे, इसलिए कुल आकार 4x कच्चा डेटा आकार था।


7

डिस्क-डिस्क संरचनाएँ ओवरहेड हैं:

  • पंक्ति हैडर
  • null बिटमैप + पॉइंटर
  • चर लंबाई स्तंभ ऑफसेट
  • पंक्ति संस्करण संकेत (वैकल्पिक)
  • ...

आपके पास 2 x 4 बाइट्स इंट कॉलम हैं

  • 4 बाइट्स पंक्ति हेडर
  • NULL बिटमैप के लिए 2 बाइट पॉइंटर
  • 2 इंट कॉलम के लिए 8 बाइट्स
  • 3 बाइट्स पूर्ण बिटमैप

वाह 17 बाइट्स!

आप अपनी दूसरी परीक्षा तालिका के लिए वही कर सकते हैं जिसमें आपके मूल की तरह अधिक ओवरहेड है:

  • चर-लंबाई वाले स्तंभों की गिनती के लिए 2 बाइट्स
  • प्रति चर लंबाई कॉलम में 2 बाइट्स

अंतर क्यों? इसके अलावा (मैं इनसे लिंक नहीं करूंगा)

  • क्या आपने कभी उन्हें ख़राब करने के लिए अनुक्रमणिकाओं का पुनर्निर्माण किया है?
  • हटाए गए स्थान को पुनः प्राप्त नहीं करता है
  • यदि आप मध्य में सम्मिलित करते हैं तो डेटा पृष्ठ विभाजित हो जाएंगे
  • अद्यतन आगे संकेत हो सकता है (एक अंतर छोड़ देता है)
  • पंक्ति अतिप्रवाह
  • अनुक्रमणिका पुनर्निर्माण या DBCC स्पष्ट बिना varchar स्तंभ हटा दिया
  • हीप या टेबल (हीप का कोई क्लस्टर इंडेक्स नहीं है = सभी रिकॉर्ड बिखरे हुए हैं)
  • RCSI अलगाव स्तर (प्रति पंक्ति अतिरिक्त 14 बाइट्स)
  • अनुगामी रिक्त स्थान (SET ANSI_PADDING डिफ़ॉल्ट रूप से चालू है)। DATALENGTH का इस्तेमाल चेले से करें, LEN से नहीं
  • के साथ sp_spaceused चलाएँ @updateusage = 'true'
  • ...

इसे देखें: SQL सर्वर: एक टेबल बनाने के लिए कैसे जो एक 8 केबी पेज भरता है?

SO से:


2x4 बाइट इंट कॉलम नमूना 100% सही नहीं है। आपके पास 4 बाइट पंक्ति हेडर (2 स्टेटस बाइट्स और निश्चित लंबाई डेटा आकार के लिए 2 बाइट्स) होंगे। फिर आपके पास डेटा के लिए 2x4 बाइट्स होंगे। कॉलम गिनती के लिए दो बाइट्स और अशक्त बिटमैप के लिए एक एकल बाइट, 15 बाइट्स की कुल रिकॉर्ड लंबाई, 17 नहीं।
मार्क एस। रासमुसेन

@ मर्क एस रासमुसेन: आपको "निर्धारित लंबाई डेटा आकार के लिए 2 बाइट्स" कहां से मिलते हैं? MSDN? और शून्य बिटमैप हमेशा 3 बाइट्स होता है: sqlskills.com/blogs/paul/post/… + msdn.microsoft.com/en-us/library/ms178085%28v=sql.90/29.aspx
gbn

वाह, महान विस्तार! मैंने VARCHARअपने अनुमान में एस के लंबाई क्षेत्र के लिए जिम्मेदार है, लेकिन स्तंभों की गिनती के लिए नहीं। इस तालिका में कोई NULLable फ़ील्ड नहीं है (जिसका उल्लेख होना चाहिए), क्या यह अभी भी उनके लिए बाइट आवंटित करता है?
जॉन ऑफ ऑल ट्रेड्स

क्या पुन: निर्माण सूचकांक आवश्यक स्थान के डेटा भाग को प्रभावित करेंगे ? शायद क्लस्टर इंडेक्स का पुनर्निर्माण होगा। आवेषण बीच में होते हैं, बहुत, हालांकि अगर मैंने क्लस्टरिंग फ़ील्ड के आदेश को स्वैप किया जो बंद हो जाएगा। बाकी के अधिकांश इस मामले में लागू नहीं होने चाहिए, लेकिन यह सामान्य मामले के लिए महान संदर्भ है। मैं आपके लिंक देखूंगा। अच्छी चीज़!
जॉन ऑफ ऑल ट्रेड्स

1
@ जीबी निश्चित लंबाई डेटा आकार के लिए 2 बाइट्स 4 बाइट पंक्ति हैडर का हिस्सा है जिसका आप उल्लेख करते हैं। यह पॉइंटर है जो कॉलम की गिनती / नल बिटमैप की निश्चित डेटा लंबाई भाग / शुरुआत के अंत तक इंगित करता है। NULL बिटमैप हमेशा तीन बाइट्स नहीं होता है। यदि आप कॉलम की गिनती शामिल करते हैं, तो यह न्यूनतम तीन बाइट्स होगा, लेकिन अधिक हो सकता है - मैंने अपने विवरण में बिटमैप और कॉलम की गिनती को विभाजित किया। इसके अलावा, NULL बिटमैप हमेशा मौजूद नहीं होता है , हालांकि यह इस मामले में होगा।
मार्क एस रासमुसेन

5

क्या समय के साथ डेटा प्रकार बदल गए हैं? क्या चर-लंबाई के कॉलम हटा दिए गए हैं? क्या अनुक्रमितों को अक्सर डीफ़्रेग्मेंट किया गया है लेकिन कभी पुनर्निर्माण नहीं किया गया है? क्या बहुत सी पंक्तियों को हटा दिया गया है या बहुत अधिक परिवर्तनशील लंबाई वाले स्तंभों को काफी अपडेट किया गया है? कुछ अच्छी चर्चा यहाँ


मुझे 97% विश्वास है कि मैंने कोई डेटा प्रकार नहीं बदला है या कोई फ़ील्ड नहीं निकाला है। अगर मैं करता, तो यह वास्तव में जल्दी होता जब मेज में बहुत कम पंक्तियाँ होतीं। कोई विलोपन या अपडेट नहीं है, डेटा केवल कभी जोड़ा गया है।
जॉन ऑफ ऑल ट्रेड्स

सुधार: वहाँ रहे हैं हटाए गए, और काफ़ी। तालिका में काफी शुद्ध वृद्धि है, इसलिए मुझे लगता है कि यह स्थान जल्दी से फिर से उपयोग किया जाएगा।
ट्रेड में जॉन ऑफ ऑल ट्रेड्स

बहुत से डेटा को हटाने के साथ पुन: उपयोग किया जा सकता है या नहीं किया जा सकता है। तालिका की क्लस्टरिंग कुंजी क्या है? क्या तालिका के मध्य में या अंत में आवेषण हैं?
मर्दानी

उस क्रम में, VARCHARऔर DATETIME2फ़ील्ड पर, क्लस्टर की गई कुंजी यौगिक है । पहले क्षेत्र के लिए सम्मिलित रूप से वितरित किया जाएगा। दूसरे क्षेत्र के लिए, नए मूल्य और हमेशा किसी भी मौजूदा से अधिक होगा।
जॉन ऑफ ऑल ट्रेड्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.