अप्रयुक्त स्थान को पुनः प्राप्त करने का प्रयास SQL ​​सर्वर में उपयोग किए गए स्थान को महत्वपूर्ण रूप से बढ़ाता है


15

मेरे पास एक उत्पादन डेटाबेस में एक तालिका है जिसका आकार 525 जीबी है, जिसमें से 383 जीबी अप्रयुक्त है:

अप्रयुक्त स्थान

मैं इस स्पेस में से कुछ को पुनः प्राप्त करना चाहूंगा, लेकिन, उत्पादन डीबी के साथ खिलवाड़ करने से पहले, मैं कम डेटा वाले टेस्ट डीबी में एक समान टेबल पर कुछ रणनीतियों का परीक्षण कर रहा हूं। इस तालिका में एक समान समस्या है:

अप्रयुक्त स्थान

तालिका के बारे में कुछ जानकारी:

  • भरण कारक 0 पर सेट है
  • लगभग 30 कॉलम हैं
  • स्तंभों में से एक LOB प्रकार की छवि है, और यह उन फ़ाइलों को संग्रहीत कर रहा है जो आकार में कुछ KB से लेकर कई सौ MB तक होती हैं
  • तालिका में इससे संबंधित कोई काल्पनिक सूचकांक नहीं है

सर्वर SQL Server 2017 (RTM-GDR) (KB4505224) - 14.0.2027.2 (X64) चला रहा है। डेटाबेस SIMPLEपुनर्प्राप्ति मॉडल का उपयोग कर रहा है ।

कुछ चीजें जो मैंने कोशिश की हैं:

  • अनुक्रमणिका का पुनर्निर्माण करना ALTER INDEX ALL ON dbo.MyTable REBUILD:। इसका नगण्य प्रभाव पड़ा।
  • अनुक्रमणिका का पुनर्गठन ALTER INDEX ALL ON dbo.MyTable REORGANIZE WITH(LOB_COMPACTION = ON):। इसका नगण्य प्रभाव पड़ा।
  • LOB स्तंभ को किसी अन्य तालिका में कॉपी किया गया, स्तंभ को गिरा दिया, स्तंभ को फिर से बनाया, और डेटा को वापस कॉपी किया (जैसा कि इस पोस्ट में उल्लिखित है: मुक्त अप्रयुक्त स्थान SQL सर्वर तालिका )। यह अप्रयुक्त स्थान को कम कर देता है, लेकिन ऐसा लगता है कि इसे केवल उपयोग किए गए स्थान में परिवर्तित करना है:

    अप्रयुक्त स्थान

  • तालिका को निर्यात करने के लिए bcp उपयोगिता का उपयोग किया, इसे छोटा किया और इसे पुनः लोड किया (जैसा कि इस पोस्ट में उल्लिखित है: तालिका के लिए अप्रयुक्त स्थान को कैसे मुक्त किया जाए )। इसने अप्रयुक्त स्थान को भी कम कर दिया और उपयोग की गई जगह को उपरोक्त छवि के समान हद तक बढ़ा दिया।

  • हालांकि इसकी अनुशंसा नहीं की गई है, मैंने DBCC SHRINKFILE और DBCC SHRINKDATABASE कमांड की कोशिश की, लेकिन उनका अप्रयुक्त स्थान पर कोई प्रभाव नहीं पड़ा।
  • दौड़ने से DBCC CLEANTABLE('myDB', 'dbo.myTable')कोई फर्क नहीं पड़ा
  • मैंने छवि और पाठ डेटाटिप्स को बनाए रखने के बाद और डेटाटाइप्स को परिवर्तनशील (अधिकतम) और varchar (अधिकतम) में परिवर्तित करने के दौरान उपरोक्त दोनों की कोशिश की है।
  • मैंने एक नए डेटाबेस में डेटा को एक नई तालिका में आयात करने की कोशिश की, और यह केवल अप्रयुक्त स्थान को उपयोग किए गए स्थान में परिवर्तित कर दिया। मैंने इस पोस्ट में इस प्रयास के विवरण को रेखांकित किया है ।

मैं उत्पादन DB पर ये प्रयास नहीं करना चाहता अगर ये वे परिणाम हैं जो मैं उम्मीद कर सकता हूं, तो:

  1. इन प्रयासों में से कुछ के बाद भी अप्रयुक्त स्थान का उपयोग किए गए स्थान में परिवर्तित क्यों किया जा रहा है? मुझे ऐसा लगता है कि मुझे इस बात की अच्छी समझ नहीं है कि हुड के नीचे क्या हो रहा है।
  2. क्या इस्तेमाल की गई जगह को बढ़ाए बिना अप्रयुक्त स्थान को कम करने के लिए मैं कुछ और कर सकता हूं?

संपादित करें: यहां डिस्क उपयोग रिपोर्ट और तालिका के लिए स्क्रिप्ट है:

डिस्क उपयोग

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[MyTable](
    [Column1]  [int] NOT NULL,
    [Column2]  [int] NOT NULL,
    [Column3]  [int] NOT NULL,
    [Column4]  [bit] NOT NULL,
    [Column5]  [tinyint] NOT NULL,
    [Column6]  [datetime] NULL,
    [Column7]  [int] NOT NULL,
    [Column8]  [varchar](100) NULL,
    [Column9]  [varchar](256) NULL,
    [Column10] [int] NULL,
    [Column11] [image] NULL,
    [Column12] [text] NULL,
    [Column13] [varchar](100) NULL,
    [Column14] [varchar](6) NULL,
    [Column15] [int] NOT NULL,
    [Column16] [bit] NOT NULL,
    [Column17] [datetime] NULL,
    [Column18] [varchar](50) NULL,
    [Column19] [varchar](50) NULL,
    [Column20] [varchar](60) NULL,
    [Column21] [varchar](20) NULL,
    [Column22] [varchar](120) NULL,
    [Column23] [varchar](4) NULL,
    [Column24] [varchar](75) NULL,
    [Column25] [char](1) NULL,
    [Column26] [varchar](50) NULL,
    [Column27] [varchar](128) NULL,
    [Column28] [varchar](50) NULL,
    [Column29] [int] NULL,
    [Column30] [text] NULL,
 CONSTRAINT [PK] PRIMARY KEY CLUSTERED 
(
    [Column1] ASC,
    [Column2] ASC,
    [Column3] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[MyTable] ADD  CONSTRAINT [DF_Column4]  DEFAULT (0) FOR [Column4]
GO
ALTER TABLE [dbo].[MyTable] ADD  CONSTRAINT [DF_Column5]  DEFAULT (0) FOR [Column5]
GO
ALTER TABLE [dbo].[MyTable] ADD  CONSTRAINT [DF_Column15]  DEFAULT (0) FOR [Column15]
GO
ALTER TABLE [dbo].[MyTable] ADD  CONSTRAINT [DF_Column16]  DEFAULT (0) FOR [Column16]
GO

मैक्स वर्नोन के उत्तर में कमांड निष्पादित करने के परिणाम इस प्रकार हैं:

╔════════════╦═══════════╦════════════╦═════════════════╦══════════════════════╦════════════════════╗
 TotalBytes  FreeBytes  TotalPages  TotalEmptyPages  PageBytesFreePercent  UnusedPagesPercent 
╠════════════╬═══════════╬════════════╬═════════════════╬══════════════════════╬════════════════════╣
  9014280192 8653594624     1100376          997178             95.998700           90.621500 
╚════════════╩═══════════╩════════════╩═════════════════╩══════════════════════╩════════════════════╝
╔═════════════╦═══════════════════╦════════════════════╗
 ObjectName   ReservedPageCount       UsedPageCount 
╠═════════════╬═══════════════════╬════════════════════╣
 dbo.MyTable            5109090             2850245 
╚═════════════╩═══════════════════╩════════════════════╝

अपडेट करें:

मैक्स वर्नोन द्वारा सुझाए गए अनुसार मैंने निम्न भाग किया:

DBCC UPDATEUSAGE (N'<database_name>', N'<table_name>');

और यहाँ उत्पादन था:

DBCC UPDATEUSAGE: Usage counts updated for table 'MyTable' (index 'PK_MyTable', partition 1):
        USED pages (LOB Data): changed from (568025) to (1019641) pages.
        RSVD pages (LOB Data): changed from (1019761) to (1019763) pages.

इसने तालिका के लिए डिस्क उपयोग को अद्यतन किया:

यहाँ छवि विवरण दर्ज करें

और समग्र डिस्क उपयोग:

यहाँ छवि विवरण दर्ज करें

तो, ऐसा लगता है कि समस्या यह थी कि SQL सर्वर द्वारा ट्रैक किए गए डिस्क उपयोग वास्तविक डिस्क उपयोग के साथ बेतहाशा आउट-सिंक हो गए थे। मैं इस मुद्दे को हल करने पर विचार करूंगा, लेकिन मुझे यह जानने में दिलचस्पी होगी कि यह पहली जगह में क्यों हुआ होगा!

जवाबों:


10

मैं पहले कदम के रूप में तालिका के खिलाफ DBCC UPDATEUSAGE चलाऊंगा , क्योंकि लक्षण असंगत स्थान उपयोग दिखाते हैं।

DBCC UPDATEUSAGE एक तालिका या सूचकांक में प्रत्येक विभाजन के लिए पंक्तियों, प्रयुक्त पृष्ठों, आरक्षित पृष्ठ, पत्ती पृष्ठ और डेटा पृष्ठ की संख्या को सही करता है। यदि सिस्टम तालिकाओं में कोई अशुद्धि नहीं है, तो DBCC UPDATEUSAGE कोई डेटा नहीं देता है। यदि अशुद्धि पाई जाती है और ठीक की जाती है और NO_INFOMSGS का उपयोग नहीं किया जाता है, तो DBCC UPDATEUSAGE सिस्टम तालिकाओं में अपडेट की जा रही पंक्तियों और स्तंभों को लौटाता है।

सिंटैक्स है:

DBCC UPDATEUSAGE (N'<database_name>', N'<table_name>');

आपके द्वारा चलाए जाने के बाद, मैं EXEC sys.sp_spaceusedतालिका के विरुद्ध दौड़ूंगा:

EXEC sys.sp_spaceused @objname = N'dbo.MyTable'
    , @updateusage = 'false' --true or false
    , @mode = 'ALL' --ALL, LOCAL_ONLY, REMOTE_ONLY
    , @oneresultset = 1;

उपरोक्त कमांड में उपयोग को अद्यतन करने का विकल्प है, लेकिन जब से आप DBCC UPDATEUSAGEपहले मैन्युअल रूप से भागे हैं , तो उस सेट को गलत पर छोड़ दें। चल रहा हैDBCC UPDATEUSAGEमैन्युअल रूप से से आपको यह देखने की अनुमति मिलती है कि क्या कुछ भी सही किया गया था।

निम्न क्वेरी को तालिका में बाइट्स का प्रतिशत और तालिका में मुक्त पृष्ठों का प्रतिशत दिखाना चाहिए। चूंकि क्वेरी एक अनिर्दिष्ट सुविधा का उपयोग करती है, इसलिए परिणामों पर भरोसा करना नासमझी है, लेकिन आउटपुट से तुलना करने पर यह सटीक लगता हैsys.sp_spaceused उच्च स्तर पर है।

यदि मुफ्त बाइट्स का प्रतिशत मुक्त पृष्ठों के प्रतिशत से काफी अधिक है, तो आपके पास आंशिक रूप से खाली पृष्ठों का एक बहुत कुछ है।

आंशिक रूप से खाली पृष्ठ कई कारणों से स्टेम कर सकते हैं, जिनमें शामिल हैं:

  1. पृष्ठ विभाजन, जहां पृष्ठ को अनुक्रमणिका में नए आवेषण को समायोजित करने के लिए विभाजित किया जाना चाहिए

  2. स्तंभ आकार के कारण स्तंभों के साथ पृष्ठ को भरने में असमर्थता।

क्वेरी undocumented sys.dm_db_database_page_allocationsगतिशील प्रबंधन फ़ंक्शन का उपयोग करती है:

;WITH dpa AS 
(
    SELECT dpa.*
        , page_free_space_percent_corrected = 
          CASE COALESCE(dpa.page_type_desc, N'')
            WHEN N'TEXT_MIX_PAGE' THEN 100 - COALESCE(dpa.page_free_space_percent, 100)
            WHEN N'TEXT_TREE_PAGE' THEN 100 - COALESCE(dpa.page_free_space_percent, 100)
            ELSE COALESCE(dpa.page_free_space_percent, 100)
          END
    FROM sys.dm_db_database_page_allocations(DB_ID(), OBJECT_ID('dbo.MyTable'), NULL, NULL, 'DETAILED') dpa
)
, src AS
(
SELECT TotalKB = COUNT_BIG(1) * 8192 / 1024
    , FreeKB = SUM((dpa.page_free_space_percent_corrected / 100) * CONVERT(bigint, 8192)) / 1024
    , TotalPages = COUNT_BIG(1)
    , TotalEmptyPages = SUM(CASE WHEN dpa.page_free_space_percent_corrected = 100 THEN 1 ELSE 0 END) --completely empty pages
FROM dpa
)
SELECT *
    , BytesFreePercent = (CONVERT(decimal(38,2), src.FreeKB) / src.TotalKB) * 100
    , UnusedPagesPercent = (CONVERT(decimal(38,2), src.TotalEmptyPages) / src.TotalPages) * 100
FROM src

आउटपुट जैसा दिखता है:

╔═════════╦════════╦════════════╦═════════════════ ╦══════════════════╦════════════════════╗
║ टोटलबी K फ्रीकेबी
╠═════════╬════════╬════════════╬═════════════════ ╬══════════════════╬════════════════════╣
║ 208 ║ 96 ║ 26 ║ 12 5 46.153800 ║ 46.153800 ║
╚═════════╩════════╩════════════╩═════════════════ ╩══════════════════╩════════════════════╝

मैंने यहाँ फंक्शन का वर्णन करते हुए एक ब्लॉग पोस्ट लिखी ।

आपके द्वारा निष्पादित किए जाने के बाद से आपके परिदृश्य में, आपको ALTER TABLE ... REBUILDबहुत कम संख्या में देखना चाहिए TotalEmptyPages, लेकिन मुझे लगता है कि आपके पास अभी भी लगभग 72% होगा BytesFreePercent

मैंने CREATE TABLEआपके परिदृश्य को फिर से बनाने के प्रयास के लिए आपकी स्क्रिप्ट का उपयोग किया है।

यह वह MCVE है जिसका मैं उपयोग कर रहा हूं:

DROP TABLE IF EXISTS dbo.MyTable;

CREATE TABLE [dbo].[MyTable](
    [Column1]  [int]            NOT NULL IDENTITY(1,1),
    [Column2]  [int]            NOT NULL,
    [Column3]  [int]            NOT NULL,
    [Column4]  [bit]            NOT NULL,
    [Column5]  [tinyint]        NOT NULL,
    [Column6]  [datetime]       NULL,
    [Column7]  [int]            NOT NULL,
    [Column8]  [varchar](100)   NULL,
    [Column9]  [varchar](256)   NULL,
    [Column10] [int]            NULL,
    [Column11] [image]          NULL,
    [Column12] [text]           NULL,
    [Column13] [varchar](100)   NULL,
    [Column14] [varchar](6)     NULL,
    [Column15] [int]            NOT NULL,
    [Column16] [bit]            NOT NULL,
    [Column17] [datetime]       NULL,
    [Column18] [varchar](50)    NULL,
    [Column19] [varchar](50)    NULL,
    [Column20] [varchar](60)    NULL,
    [Column21] [varchar](20)    NULL,
    [Column22] [varchar](120)   NULL,
    [Column23] [varchar](4)     NULL,
    [Column24] [varchar](75)    NULL,
    [Column25] [char](1)        NULL,
    [Column26] [varchar](50)    NULL,
    [Column27] [varchar](128)   NULL,
    [Column28] [varchar](50)    NULL,
    [Column29] [int]            NULL,
    [Column30] [text]           NULL,
 CONSTRAINT [PK] PRIMARY KEY CLUSTERED 
(
    [Column1] ASC,
    [Column2] ASC,
    [Column3] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

ALTER TABLE [dbo].[MyTable] ADD  CONSTRAINT [DF_Column4]  DEFAULT (0) FOR [Column4]

ALTER TABLE [dbo].[MyTable] ADD  CONSTRAINT [DF_Column5]  DEFAULT (0) FOR [Column5]

ALTER TABLE [dbo].[MyTable] ADD  CONSTRAINT [DF_Column15]  DEFAULT (0) FOR [Column15]

ALTER TABLE [dbo].[MyTable] ADD  CONSTRAINT [DF_Column16]  DEFAULT (0) FOR [Column16]
GO

INSERT INTO dbo.MyTable (
      Column2
    , Column3
    , Column4
    , Column5
    , Column6
    , Column7
    , Column8
    , Column9
    , Column10
    , Column11
    , Column12
    , Column13
    , Column14
    , Column15
    , Column16
    , Column17
    , Column18
    , Column19
    , Column20
    , Column21
    , Column22
    , Column23
    , Column24
    , Column25
    , Column26
    , Column27
    , Column28
    , Column29
    , Column30
)
VALUES (
          0
        , 0
        , 0
        , 0
        , '2019-07-09 00:00:00'
        , 1
        , REPLICATE('A', 50)    
        , REPLICATE('B', 128)   
        , 0
        , REPLICATE(CONVERT(varchar(max), 'a'), 1)
        , REPLICATE(CONVERT(varchar(max), 'b'), 9000)
        , REPLICATE('C', 50)    
        , REPLICATE('D', 3)     
        , 0
        , 0
        , '2019-07-10 00:00:00'
        , REPLICATE('E', 25)    
        , REPLICATE('F', 25)    
        , REPLICATE('G', 30)    
        , REPLICATE('H', 10)    
        , REPLICATE('I', 120)   
        , REPLICATE('J', 4)     
        , REPLICATE('K', 75)    
        , 'L'       
        , REPLICATE('M', 50)    
        , REPLICATE('N', 128)   
        , REPLICATE('O', 50)    
        , 0
        , REPLICATE(CONVERT(varchar(max), 'c'), 90000)
);
--GO 100

;WITH dpa AS 
(
    SELECT dpa.*
        , page_free_space_percent_corrected = 
          CASE COALESCE(dpa.page_type_desc, N'')
            WHEN N'TEXT_MIX_PAGE' THEN 100 - COALESCE(dpa.page_free_space_percent, 100)
            WHEN N'TEXT_TREE_PAGE' THEN 100 - COALESCE(dpa.page_free_space_percent, 100)
            ELSE COALESCE(dpa.page_free_space_percent, 100)
          END
    FROM sys.dm_db_database_page_allocations(DB_ID(), OBJECT_ID('dbo.MyTable'), NULL, NULL, 'DETAILED') dpa
)
, src AS
(
SELECT TotalKB = COUNT_BIG(1) * 8192 / 1024
    , FreeKB = SUM((dpa.page_free_space_percent_corrected / 100) * CONVERT(bigint, 8192)) / 1024
    , TotalPages = COUNT_BIG(1)
    , TotalEmptyPages = SUM(CASE WHEN dpa.page_free_space_percent_corrected = 100 THEN 1 ELSE 0 END) --completely empty pages
FROM dpa
)
SELECT *
    , BytesFreePercent = (CONVERT(decimal(38,2), src.FreeKB) / src.TotalKB) * 100
    , UnusedPagesPercent = (CONVERT(decimal(38,2), src.TotalEmptyPages) / src.TotalPages) * 100
FROM src

निम्न क्वेरी तालिका में आवंटित प्रत्येक पृष्ठ के लिए एक एकल लाइन दिखाती है, और उसी अनिर्धारित DMV का उपयोग करती है:

SELECT DatabaseName = d.name
    , ObjectName = o.name
    , IndexName = i.name
    , PartitionID = dpa.partition_id
    , dpa.allocation_unit_type_desc
    , dpa.allocated_page_file_id
    , dpa.allocated_page_page_id
    , dpa.is_allocated
    , dpa.page_free_space_percent --this seems unreliable
    , page_free_space_percent_corrected = 
        CASE COALESCE(dpa.page_type_desc, N'')
        WHEN N'TEXT_MIX_PAGE' THEN 100 - COALESCE(dpa.page_free_space_percent, 100)
        WHEN N'TEXT_TREE_PAGE' THEN 100 - COALESCE(dpa.page_free_space_percent, 100)
        ELSE COALESCE(dpa.page_free_space_percent, 100)
        END
    , dpa.page_type_desc
    , dpa.is_page_compressed
    , dpa.has_ghost_records
FROM sys.dm_db_database_page_allocations(DB_ID(), OBJECT_ID('dbo.MyTable'), NULL, NULL, 'DETAILED') dpa
    LEFT JOIN sys.databases d ON dpa.database_id = d.database_id
    LEFT JOIN sys.objects o ON dpa.object_id = o.object_id
    LEFT JOIN sys.indexes i ON dpa.object_id = i.object_id AND dpa.index_id = i.index_id
WHERE dpa.database_id = DB_ID() --sanity check for sys.objects and sys.indexes

यदि आप इसे अपने परीक्षण वातावरण में अपनी वास्तविक तालिका के विरुद्ध चलाते हैं, तो आउटपुट बहुत सी पंक्तियाँ दिखाएगा , लेकिन यह आपको यह देखने की अनुमति दे सकता है कि समस्या कहाँ है।

क्या आप निम्नलिखित स्क्रिप्ट चला सकते हैं और अपने प्रश्न में परिणाम पोस्ट कर सकते हैं? मैं बस यह सुनिश्चित करने की कोशिश कर रहा हूं कि हम एक ही पृष्ठ पर हैं।

SELECT ObjectName = s.name + N'.' + o.name
    , ReservedPageCount = SUM(dps.reserved_page_count)
    , UsePageCount = SUM(dps.used_page_count)
FROM sys.schemas s
    INNER JOIN sys.objects o ON s.schema_id = o.schema_id
    INNER JOIN sys.partitions p ON o.object_id = p.object_id
    INNER JOIN sys.dm_db_partition_stats dps ON p.object_id = dps.object_id
WHERE s.name = N'dbo'
    AND o.name = N'MyTable'
GROUP BY s.name + N'.' + o.name;

2
चल रहे DBCC UPDATEUSAGEअप्रयुक्त स्थान और अप्रयुक्त पृष्ठ गणना को अद्यतन किया। ऐसा लगता है कि SQL सर्वर द्वारा रिपोर्ट की जा रही डिस्क का उपयोग और पृष्ठ की जानकारी सिंक से बहुत बाहर थी - मैंने विवरण के साथ अपनी पोस्ट को अपडेट किया। मैं इस बारे में उत्सुक हूं कि यह पहली बार में कैसे हुआ होगा, लेकिन कम से कम समस्या पाई गई। आपकी सभी मदद के लिए धन्यवाद, मैं वास्तव में इसकी सराहना करता हूं!
केन

0

स्तंभों में से एक LOB प्रकार की छवि है, और यह उन फ़ाइलों को संग्रहीत कर रहा है जो आकार में कुछ KB से लेकर कई सौ MB तक होती हैं

आप आंतरिक विखंडन का अनुभव कर सकते हैं। इस तालिका के लिए पृष्ठ विखंडन
क्या है ? और ऑफ-पंक्ति पृष्ठों से अलग इन-रो के लिए विखंडन है?

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


मुझे नहीं लगता कि विखंडन मुद्दा है। इंडेक्स के पुनर्निर्माण के बाद, क्लस्टर इंडेक्स के लिए विखंडन 0.45% है और इसकी पृष्ठ परिपूर्णता 98.93% है।
केन ०

यदि आप बहुत बड़ी पंक्तियों या LOB डेटा से पीड़ित हैं, जो 8KB पृष्ठों में अच्छी तरह से फिट नहीं है, तो किसी तालिका या अनुक्रमणिका को फिर से बनाना मदद नहीं करेगा। यह मैक्स वेरनॉन ने और अधिक विस्तार से बताया है: "आपके पास आंशिक रूप से खाली पृष्ठ बहुत हैं।" आंतरिक विखंडन भी कहा जाता है
DrTrunks Bell

-3

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


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

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

-3

केवल एक बार जब मैं एक DB को सिकोड़ने में असमर्थ रहा हूँ और स्थान को पुनः प्राप्त कर रहा हूँ, क्योंकि आप DB के प्रारंभिक आकार से परे एक DB को सिकोड़ नहीं सकते हैं जब इसे बनाया गया था। उदाहरण के लिए, यदि आपका DB उत्पादन DB की एक प्रति है और आपने सबसे पहले 525GB पर DB बनाया है, तो sql सर्वर आपको 525GB से नीचे के आकार को सिकोड़ने की अनुमति नहीं देगा, भले ही आप DB से कितना डेटा हटा दें। लेकिन अगर DB 383GB से नीचे बनाया गया था और फिर 525GB तक बढ़ गया तो आपको स्पेस को दोबारा प्राप्त करने में कोई परेशानी नहीं होनी चाहिए। मैंने लंबे समय से सोचा है कि यह Microsoft द्वारा एक मूर्ख और मनमाना प्रतिबंध है।

डेटाबेस को केवल उसके प्रारंभिक आकार तक सिकोड़ें जो डेटाबेस बनाने के बाद सेट किया गया है


सवाल एक डेटाबेस को सिकोड़ने के बारे में नहीं है (और अगर यह था, तो इसे सिकोड़ने की क्षमता प्रारंभिक आकार क्षेत्र के बाद इस्तेमाल की गई जगह पर निर्भर करती है)
eckes

जब तक अप्रयुक्त स्थान है, तब तक मूल आकार की परवाह किए बिना एमबी के एक जोड़े को डेटाबेस को सिकोड़ना संभव है। यह जरूरी नहीं है कि यह एक अच्छा विचार है, लेकिन डेटाबेस को सिकोड़ने के लिए मेरे पास कई मौके हैं और कभी भी इस तरह की सीमा में नहीं रहना चाहिए।
रे

-3

मैं उत्पादन बक्से पर पहले इस समस्या का सामना कर चुका हूं, आपको जो करने की आवश्यकता है वह प्रत्येक तालिका (उस क्रम में) के लिए तालिकाओं और अनुक्रमितों का पुनर्निर्माण करना है।

यहाँ वह तालिका है जिसका उपयोग मैं तालिकाओं को जाँच में रखने के लिए करता हूँ। यह आपको यह निर्धारित करने में मदद करेगा कि किन तालिकाओं को फिर से बनाने की आवश्यकता है, और उन SQL प्रश्नों को बनाएं जिन्हें आपको चलाने की आवश्यकता है। यह क्वेरी 1MB से अधिक अप्रयुक्त स्थान और 5% अप्रयुक्त अनुपात वाले लोगों तक सीमित है, ताकि आप केवल उसी चीज़ का पुनर्निर्माण करें जो आपको वास्तव में ध्यान केंद्रित करने की आवश्यकता है:

SELECT  'alter table [' + t.NAME + '] rebuild;' AS SQL1, 'alter index all on [' + t.NAME + '] rebuild;' as SQL2, t.NAME AS TableName, p.rows AS RowCounts, SUM(a.total_pages) * 8/1024 AS TotalSpaceMB,  SUM(a.used_pages) * 8/1024 AS UsedSpaceMB,  (SUM(a.total_pages) - SUM(a.used_pages)) * 8/1024 AS UnusedSpaceMB, case when SUM(a.total_pages)=0 then 0 else (SUM(a.total_pages) - SUM(a.used_pages))*100/SUM(a.total_pages) end as Ratio  FROM     sys.tables t (nolock) INNER JOIN       sys.indexes i (nolock)  ON t.OBJECT_ID = i.object_id INNER JOIN  sys.partitions p (nolock) ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id INNER JOIN  sys.allocation_units a (nolock) ON p.partition_id = a.container_id LEFT OUTER JOIN  sys.schemas s (nolock) ON t.schema_id = s.schema_id WHERE  t.is_ms_shipped = 0 AND i.OBJECT_ID > 255  GROUP BY  t.Name, s.Name, p.Rows  
having  (SUM(a.total_pages) - SUM(a.used_pages)) * 8/1024>1
and (SUM(a.total_pages) - SUM(a.used_pages))*100/SUM(a.total_pages)>5
ORDER BY    5 desc

तालिका के पुनर्निर्माण, जैसा कि ओपी ने कहा है कि, अधिकांश विखंडन से छुटकारा मिलेगा। मुझे संदेह है कि एक और पुनर्निर्माण करने से आगे मदद मिलेगी।
मैक्स वेरनॉन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.