मुक्त अप्रयुक्त अंतरिक्ष SQL सर्वर तालिका


11

मेरे पास SQL ​​सर्वर 2012 एक्सप्रेस में एक तालिका है जिसमें बहुत अधिक अप्रयुक्त स्थान है।

मुझे डेटाबेस में स्थान खाली करने की आवश्यकता है।

| NAME | ROWS | आरक्षित | DATA | INDEX_SIZE | UNUSED |
| ------------- | -------- | -------------- | ----------- --- | ------------ | -------------- |
| MyTableName | 158890 | 8928296 केबी | 5760944 केबी | 2248 केबी | 3165104 केबी |

3165104KB जारी करने के लिए मुझे SQL कैसे मिलेगा?

मैंने पहले ही कोशिश की है:

Alter table MyTableName Rebuild
DBCC CLEANTABLE (MyDbName,"MyTableName ", 0)
ALTER INDEX ALL ON MyTableName REORGANIZE ; 
ALTER INDEX PK_Image ON MyTableName REBUILD WITH (ONLINE = OFF) 

यहाँ तालिका है:

CREATE TABLE [dbo].[MyTableName](
    [ImageID] [int] IDENTITY(1,1) NOT NULL,
    [DateScan] [datetime] NULL,
    [ScanImage] [image] NULL,
 CONSTRAINT [PK_Image] PRIMARY KEY CLUSTERED 
(
    [ImageID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
    ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 100) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

केवल एक चीज जो हमने की है, उसे ScanImageहर पंक्ति में एक बहुत छोटी छवि के साथ बदल दिया गया है (यह इतना अप्रयुक्त स्थान है)।

जवाबों:


10

हमारे द्वारा की जाने वाली एक ही चीज़ ScanImageको हर पंक्ति पर एक बहुत छोटी छवि के साथ बदल दिया जाता है (यह है कि कितनी अप्रयुक्त जगह है)

कुछ प्रयोग करने से सबसे अधिक प्रभावी विधि आवंटन इकाई को गिराना और इसे फिर से खोलना होगा (यदि आपके पास ऐसा करने के लिए एक रखरखाव विंडो है)।

उदाहरण कोड जिसने प्रश्न में तालिका संरचना के साथ मेरे लिए सबसे अच्छी जगह कमी प्राप्त की है:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

SET XACT_ABORT ON;

BEGIN TRAN

SELECT [ImageID],
       [ScanImage]
INTO   #Temp
FROM   [dbo].[MyTableName]

ALTER TABLE [dbo].[MyTableName]
  DROP COLUMN [ScanImage]

/*Allocation unit not removed until after this*/
ALTER INDEX PK_Image ON MyTableName REBUILD

ALTER TABLE [dbo].[MyTableName]
  ADD [ScanImage] IMAGE NULL

UPDATE [dbo].[MyTableName]
SET    [ScanImage] = T.[ScanImage]
FROM   [dbo].[MyTableName] M
       JOIN #Temp T
         ON M.ImageID = T.[ImageID]

DROP TABLE #Temp

COMMIT 

सब कुछ एक लेन-देन में है इसलिए यदि मशीन दुर्घटनाग्रस्त हो जाती है तो उसे वापस ले जाया जाएगा। शायद कुछ त्रुटि से निपटने या कम से कम कर सकता है SET XACT_ABORT ON। मैं SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;किसी भी समवर्ती संशोधनों को नकल के दौरान या उसके बाद होने से रोकता था और खो जाता था।

imageसभी पंक्तियों में एक के आकार को कम करने के बाद आरक्षित LOB पृष्ठों की संख्या इस प्रकार थी:

+ ------------------------------------------------- - + --------------------- + ------------------------- +
| घटना | lob_used_page_count | lob_reserved_page_count |
+ ------------------------------------------------- - + --------------------- + ------------------------- +
| 100,000 बाइट डेटा के साथ 10,000 पंक्तियों को सम्मिलित किया गया | 135005 | 135017 |
| सभी पंक्तियों को 10,000 बाइट छवि डेटा में अपडेट किया गया | 31251 | 135012 |
| पुनर्गठन | 23687 | 25629 |
| छवि डेटा ड्रॉप और पुनः जोड़ें | 13485 | 13489 |
+ ------------------------------------------------- - + --------------------- + ------------------------- +

1
या अगर टेबल बड़ी है तो BCP आउट डेटा और उसके बाद BULK INSERT को मेंटेनेंस विंडो के दौरान वापस कर दें।
परिजन शाह

6

प्रयत्न

ALTER INDEX PK_Image ON MyTableName REBUILD WITH (ONLINE = OFF)

यह क्लस्टर किए गए इंडेक्स को फिर से बनाता है, इसलिए ऑपरेशन को पूरा करने के लिए आपको अपने डेटाबेस में अतिरिक्त कमरे की आवश्यकता होगी। यदि आपके पास कोई अतिरिक्त कमरा नहीं है क्योंकि आपकी डिस्क भरी हुई है, तो आप संभवतः डेटाबेस में (एक अलग डिस्क पर) एक नई डेटा फ़ाइल जोड़ सकते हैं और तालिका को उसमें स्थानांतरित कर सकते हैं।

यह भी संभव है कि क्लस्टर इंडेक्स को 100% से कम एक फिलिक्टर के साथ परिभाषित किया गया है। उदाहरण के लिए, 66% के लिए भरने वाले कारक होने से, भविष्य के उपयोग के लिए प्रत्येक डेटा पृष्ठ का 1/3 खाली हो जाएगा। यदि यह वह समस्या है जिसका उपयोग करके आप भरण कारक को संशोधित कर सकते हैंALTER INDEX PK_Image ON MyTableName REBUILD WITH (ONLINE = OFF, FILLFACTOR=100)

यदि आपने हाल ही में तालिका से एक चर लंबाई क्षेत्र गिरा दिया है, तो आप भी कोशिश कर सकते हैं DBCC CLEANTABLE( Databasename, "MyTableName")

ऑनलाइन पुस्तकें (BOL) का http://technet.microsoft.com/en-us/library/ms188388%28v=sql.100%29.aspx पर अनुक्रमणिका के पुनर्निर्माण पर एक शानदार लेख है।


2

सुनिश्चित करें कि DB रिकवरी मोड है SIMPLE

के रूप में कॉलम बदल VARBINARY(MAX)

फिर डेटा को पूरी तरह से नई तालिका में कॉपी करने का प्रयास करें।

नई तालिका आकार का उपयोग कर की जाँच करें sp_spaceused "tablename"। यदि आप तालिका के अप्रयुक्त स्थान से संतुष्ट हैं, तो तालिका नाम निर्दिष्ट किए बिना समान कमांड का उपयोग करके डेटाबेस के अप्रयुक्त स्थान की जांच करें। वह स्थान अभी भी डेटाबेस फ़ाइलों के भीतर है और ओएस के लिए जारी नहीं किया गया है।

आप मूल तालिका को छोड़ सकते हैं और नई तालिका का नाम बदल सकते हैं, या फिर वही काम कर सकते हैं, और मूल तालिका नाम का उपयोग कर सकते हैं यदि आप नाम बदलने के संचालन पर भरोसा नहीं करते हैं, (मुझे पूरी तरह से भरोसा नहीं है)।

यदि यह काम करता है तो अंतिम चरण आसान है: आप जानते हैं कि फ़ाइलों को कैसे सिकोड़ें और अप्रयुक्त स्थान को छोड़ दें।

यदि कोई विदेशी कुंजी है, तो उनकी परिभाषाएँ रिकॉर्ड करें, उन्हें छोड़ें, मेरे द्वारा बताए गए कार्यों को निष्पादित करें और बाद में विदेशी कुंजियों को फिर से बनाएँ। बेशक इसमें समय लगेगा और यह ऑपरेशन ऑफ टाइम के दौरान किया जाना चाहिए। यह पूरा कार्य स्क्रिप्ट के माध्यम से किया जा सकता है और साथ ही इसे रात भर चलने दिया जा सकता है।


1

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

इसके लायक क्या है, हमने डेटाबेस से ब्लॉब स्पेस को पुनः प्राप्त किया है, यदि वे निम्न चरणों द्वारा बहुत बड़े नहीं हैं। (हालांकि, जब से आप SQL सर्वर एक्सप्रेस का उपयोग कर रहे हैं, आपके पास यह कोशिश करने के लिए जगह नहीं हो सकती है।)

  1. फ़ाइल समूह में एक नई फ़ाइल जोड़ें।
  2. भागो DBCC SHRINKFILE(file, EMPTYFILE)। चूंकि आप एमडीएफ को सिकोड़ रहे हैं, इसलिए यह अंततः विफल हो जाएगा, क्योंकि सिस्टम मेटाडेटा को स्थानांतरित नहीं किया जा सकता है। हालाँकि, खाली बूँद आवंटन स्थानांतरित नहीं होते हैं।
  3. भागो DBCC SHRINKFILE(newfile,EMPTYFILE)। यह डेटा को पीछे ले जाएगा, अतिरिक्त स्थान को घटाएगा।
  4. फ़ाइल समूह से नई फ़ाइल (अब खाली) ड्रॉप करें।

यह पपड़ी की सूजन को खत्म करता है। मुझे यह उल्लेख करना चाहिए कि हमने इस तकनीक का उपयोग मुख्य रूप से अपग्रेड स्क्रिप्ट के परीक्षण के लिए ज्यादातर खाली डेटाबेस बनाने के लिए किया है।


-1

क्लस्टर किए गए इंडेक्स को फिर से व्यवस्थित करें - कि किसी के पास नोड्स पर डेटा है, इसलिए .... इसकी संभावना खंडित है।


मैंने दौड़ने की कोशिश की है: ALTER INDEX ALL ON [MyTableName] REORGANIZE;
DermFrench

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