डेटाबेस फ़ाइल पर varchar कॉलम के आकार को कम करने से क्या प्रभाव पड़ेगा?


15

हमारे डेटाबेस में हमारे पास कई टेबल VARCHAR(MAX)हैं जिनमें कॉलम हैं VARCHAR(500)(या अधिकतम से बहुत छोटा) पर्याप्त होगा। स्वाभाविक रूप से मैं इन्हें साफ करना चाहता हूं, और आकार को और अधिक उचित स्तरों तक ले जाना चाहता हूं। ऐसा करने के लिए 'कैसे' मुझे समझ में आता है: मेरा सवाल यह है कि इन कॉलमों को डिस्क पर पृष्ठों और एक्सटेंन्ट्स में क्या बदल देगा? (जब आप एक कॉलम को आगे बढ़ाते हैं तो क्या होता है, इसके बारे में बहुत सारी जानकारी होती है, लेकिन जब आप एक को सिकोड़ते हैं तो क्या होता है, इसकी जानकारी पाने में परेशानी होती है।)

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

अग्रिम में धन्यवाद!

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

मेरे पास 20 टेबल हैं जिन्हें मैं देख रहा हूं, हालांकि उनमें से केवल आधे की संख्या 1,000 से अधिक है। सबसे बड़ी में लगभग एक लाख पंक्तियाँ हैं। सबसे खराब अपराधी 350,000 पंक्तियों और चार VARCHAR(MAX)स्तंभों वाली एक तालिका है जो VARCHAR(500)स्तर तक सिकुड़ सकती है।

जवाबों:


12

पहली चीजें पहले: तालिका में कितना डेटा है? पंक्तियों की संख्या और तालिका का आकार?

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

तीसरा: एक चर-लंबाई क्षेत्र का आकार बढ़ाना (यह मानते हुए कि आप 8060 बाइट सीमा से अधिक नहीं हैं) एक साधारण मेटा-डेटा ऑपरेशन है क्योंकि इस तरह के ऑपरेशन के लिए कोई वास्तविक डेटा नहीं बदल रहा होगा। लेकिन, दूसरी ओर, चर-लंबाई क्षेत्र के आकार को कम करना, यहां तक ​​कि स्पष्ट रूप से काम करने के लिए अधिक से अधिक, यह एक साधारण मेटा-डेटा परिवर्तन नहीं है, क्योंकि SQL सर्वर को पता नहीं है, सभी पंक्तियों को स्कैन करने से पहले , कि नया अनुरोध किया गया आकार मान्य है।

इसलिए: हाँ, यह समय की अवधि के लिए तालिका को लॉक कर देगा । कितना समय है? खैर, यहाँ परीक्षण है कि मैंने अभी किया था:

मेरे पास कुछ अन्य परीक्षण से, एक एकल INT NOT NULLफ़ील्ड और 1 मिलियन पंक्तियों वाली एक तालिका थी । मैंने इसे इस परीक्षण के माध्यम से एक नई तालिका में कॉपी किया:

SELECT *, CONVERT(NVARCHAR(MAX), NEWID()) AS [StringField]
INTO dbo.ResizeTest
FROM dbo.ClusteredUnique;

इस तरह से मैं एक ऐसे MAXक्षेत्र के परिदृश्य के साथ शुरू कर रहा था (मुझे सिर्फ एहसास हुआ कि आपके पास है VARCHARऔर मैं उपयोग कर रहा हूं NVARCHAR, लेकिन यह उस व्यवहार को नहीं बदलना चाहिए जो मैं देख रहा हूं) जिसे मैं तब बदल सकता था 500। और इसमें ऐसा डेटा है जो 500 अक्षरों के भीतर आसानी से फिट हो सकता है। जिसमें कुछ मिनट लगे।

मैं फिर भागा:

ALTER TABLE dbo.ResizeTest ALTER COLUMN [StringField] NVARCHAR(500) NULL;

और यह सिर्फ 11 मिनट से अधिक समय लगा।

मैंने बस फिर से परीक्षण किया, इस बार [ResizeTest]तालिका को गिरा दिया और दोनों NVARCHARको बदलकर बस VARCHAR, केवल सुपर-सुनिश्चित होने के लिए कि मैं सेब की तुलना किसी ऐसी चीज से कर रहा हूं जो कम से कम एक सेब की तरह दिखती है ;-)।

प्रारंभिक तालिका निर्माण में 20 ALTER TABLEमिनट लगे जबकि 2 मिनट लगे।

इसलिए, डाउनटाइम का आकलन करने के संदर्भ में, यह वास्तव में करना मुश्किल है क्योंकि यह डिस्क I / O गति पर आधारित है, चाहे डेटा फ़ाइल और / या लेनदेन लॉग आदि पर किसी भी ऑटो-विकास संचालन की आवश्यकता हो या नहीं। शायद इस बात का एक बड़ा हिस्सा है कि मेरे पहले परीक्षण को बदलने में 11 मिनट क्यों लगे और दूसरा, डेटा के VARCHARआधे आकार के होने के बावजूद NVARCHAR, केवल 2 मिनट लगे (यानी उस बिंदु पर फाइलें पूर्व-विकसित थीं)। लेकिन फिर भी, आपको यह ध्यान रखना चाहिए कि मेरा परीक्षण मेरे लैपटॉप पर चल रहा है जो सबसे तेज़ डिस्क नहीं है, लेकिन यह 2 छोटे कॉलमों की सिर्फ 1 मिलियन पंक्तियाँ (22 या इतनी बाइट्स प्रति पंक्ति) थी।

और जब से आपने पूछा कि यह डेटा पृष्ठों पर क्या करेगा, तो यहां आपका जवाब है। मैंने sp_spaceusedटेबल बनाने के बाद, करने के बाद ALTER COLUMN, और करने के बाद किया ALTER TABLE dbo.ResizeTest REBUILD;। परिणाम (निम्नलिखित संख्याएँ दूसरे परीक्षण के उपयोग पर आधारित हैं VARCHAR, न कि पहली परीक्षा का उपयोग करके NVARCHAR):

After initial table creation:        526,344 KB
After ALTER COLUMN VARCHAR(500):   1,031,688 KB  <--- !! Yikes!!
After ALTER REBUILD:                 526,472 KB

यदि आप ऑपरेशन को कम से कम समय तक रखने की आवश्यकता के बारे में चिंतित हैं, तो एक लेख देखें जो मैंने बस ऐसा करने के बारे में लिखा था: सिक्योरिटीज में 100 मिलियन रो (या अधिक) टेबल। Srsly! (मुफ्त पंजीकरण आवश्यक)।


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

@nateirvin सुनने में अच्छा है। आप संभवतः ALTER TABLEप्रत्येक शॉट को एक शॉट में अलग करके, एक कॉलम को अल्पविराम से अलग करके ऑपरेशन को गति दे सकते हैं । यदि लेन-देन बहुत बड़ा है, तो तालिका को प्रत्येक कॉलम के आधे हिस्से के 2 पूर्व कथन में विभाजित करें। और तालिका कितनी बड़ी हो जाती है, इसके आधार पर, आप प्रत्येक दो बयानों के बीच एक REBUILD भी कर सकते हैं। कुछ के साथ खेलने के लिए। इसके अलावा, ध्यान रखें कि ऑपरेशन संभवतः उस अवधि के लिए स्कीमा-लॉक ले जाएगा जो तालिका तक सभी पहुंच को अवरुद्ध कर देगा।
सोलोमन रटज़की

1
मैंने प्रत्येक को ALTERअलग - अलग किया ताकि मैं हर एक के बीच आकार परिवर्तन को ट्रैक कर सकूं, लेकिन निश्चित रूप से जानना अच्छा होगा। धन्यवाद!
नैटविरिन

1

जब से मैं परिवर्तन कथन को चलाने के लिए एकत्रित हुआ हूं, तब तक बहुत समय नहीं लेना चाहिए जब तक कि तालिका किसी अन्य प्रक्रिया द्वारा लॉक न हो जाए। Gbn के अनुसार यह सिर्फ एक मेटाडाटा परिवर्तन है: /programming/7261909/is-it-bad-to-use-alter-table-to-resize-a-varchar-column-to-a-larger आकार के

इसके अलावा, यह कैसे संग्रहीत किया जाता है, ऐसा लगता है कि SQL सर्वर ने 8k पृष्ठ में varchar डेटा संग्रहीत किया है जब तक कि यह एक पूरे पृष्ठ को भरता नहीं है, जो इस बिंदु पर इसे एक पॉइंटर के साथ बदल देता है और इसे BLOB के रूप में संग्रहीत करता है।

मैं मान रहा हूं कि जब आप लंबाई बदलते हैं, तो आप किसी भी रिकॉर्ड को तोड़ नहीं पाएंगे। यदि ऐसा है, तो अधिकतम डेटा जो आप varchar (500) में परिवर्तित कर रहे हैं, कम से कम 502 बाइट्स लंबा होना चाहिए और एक पॉइंटर नहीं होना चाहिए।

तो, जब तक आप किसी भी डेटा को छोटा नहीं कर रहे हैं, तब तक छोटी कहानी, बहुत कुछ नहीं बदलना चाहिए।


5
यह बिल्कुल गलत है। मैं नीचे नहीं जाऊंगा क्योंकि आपने वास्तव में इसका परीक्षण किया था (जो कुछ लोगों की तुलना में अधिक है, इसलिए ऐसा करने के लिए धन्यवाद), लेकिन आपको इस पैमाने पर परीक्षण करने की आवश्यकता है। आप जिस उत्तर से जुड़े थे, वह आकार बढ़ाने के बारे में था, घटने के बारे में नहीं। वे दो बहुत अलग ऑपरेशन हैं।
सोलोमन रटज़की
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.