2016-06-21 58 views
0

問題: 在Sql server 2012中,儘可能多地使用盡可能多的碎片空間來回收儘可能多的保留空間的最佳方式是什麼?使用盡可能少的碎片回收分區中的可用空間

背景:

我們的SQL服務器上的磁盤空間和HW + SW的一部分升級,我們將數據文件移動到不同的服務器上運行的低 - 因爲這個原因,我們要減少的大小數據文件(以防止不必要的移動'保留空間',我們正在談論淚滴)。我也想通過分區來執行此分區,以便能夠運行超時並限制生產影響。

一種方法我試過(每個分區上的巨大消費國表與單指數):對於一些分區

ALTER TABLE <Tbl> 
REBUILD PARTITION = <PartitionId> WITH (DATA_COMPRESSION = PAGE) 
GO 

--I know this is bad practice - but I need to reclaim space to speed up moving 
DBCC SHRINKFILE(<PartitionName>, target_size = 10) 
GO 

-- This is to mitigate the impact of shrinkfile 
ALTER TABLE <Tbl> 
REBUILD PARTITION = <PartitionId> 
GO 


--Run this in the end (and I run also between the individual tasks) to see impact on index fragmentation 
SELECT * FROM sys.dm_db_index_physical_stats 
    (DB_ID(<DbName>), OBJECT_ID(<TblName>), <IndexId>, <PartitionId>, 'SAMPLED'); 
GO 

在測試environemnt這個產量很大的成績(0%gragmentation和接近0%「浪費」空間因爲考慮到下一階段是通過線纜傳輸數據),但我有一個分區情況,SHRINKFILE顯着減小了大小,但是導致99.99%的碎片; REBUILD解決了碎片問題,但將文件組大小加倍(一半是保留空間) - 這可能是因爲重建會從頭開始創建索引。如果我之後收縮,我可以回收空間,但同樣會造成巨大的碎片化。這可以繞着圈走

現在我試圖運行重新組織萎縮文件組:

ALTER INDEX <IdxName> on <Tbl> REORGANIZE PARTITION = <PartitionId> 

由於這應該希望解決索引碎片沒有增長的數據文件。 但是:

  • 是一個好主意在99.99%碎片索引上運行重組?
  • 結果是否可以與運行重建相比/差/優?

我正在考慮的另一個選擇是重建分區到全新的文件組,但這需要操縱分區模式 - 並且我希望儘可能簡化過程。

回答

1

如何使用壓縮備份數據庫並將其還原到新服務器。備份不包括未使用的空間。

+0

這是非常有趣的提示,我不知道!我會等待看看是否有其他建議。原因是我更喜歡能夠以最少的額外存儲成本準備數據傳輸的解決方案(由於各種原因,我們讓存儲容量從16T增加到14T,並且位於我們目前沒有額外存儲的遠程位置 - 爲了最大限度地減少現場維護時間,我試圖準備儘可能多的遠程維護 - 所以最初我們計劃將數據庫壓縮到位並通過分離連接進行復制) – Jan

0

這不是最好的答案,但這是我所做的最好解決我的具體情況 - 特別是缺少任何其他可用空間將被使用 - 所以我甚至無法使用備份恢復辦法;和在較小(過夜)批次中執行操作的能力

我想發佈它,以防有人會發現它有幫助。

但是 - 確保您的數據庫至少擁有與您當前佔用的數據庫同樣多的可用空間,然後您可以使用更合適的解決方案(例如,我標記爲答案的壓縮備份建議。

--This is just so that anything doesn't interract with table during the entire process. 
-- reorganize is being done online; but I want the process to finish as fast as possible and 
-- app logic is resilient to not seeing the table for while 
exec sp_rename <tbl_orig>, <tbl> 
GO 

print 'starting compressing: ' + CAST(GETDATE() AS NVARCHAR) 
GO 

-- this is to enable compression on the partition 
ALTER TABLE <tbl> 
REBUILD PARTITION = <PartitionId> WITH (DATA_COMPRESSION = PAGE) 
GO 

print 'Compressing done: ' + CAST(GETDATE() AS NVARCHAR) 
GO 

-- recaliaming all free space; potentially very bad fragmentation is possible 
DBCC SHRINKFILE(<DataFile>, target_size = 10) 
GO 

print 'shrinking done: ' + CAST(GETDATE() AS NVARCHAR) 
GO 

-- solve the fragmentation without giving up on any reclaimed space. Rebuild would use some additional space. 
-- This assumes that my partitions are stored in dedicated filegroups (which is always a good idea) 
ALTER INDEX <IdxName> on <tbl> REORGANIZE PARTITION = <PartitionId> 
GO 

print 'index reorganizing done: ' + CAST(GETDATE() AS NVARCHAR) 
GO 

-- see the stats 
SELECT * FROM sys.dm_db_index_physical_stats 
    (DB_ID(<DBName>), OBJECT_ID(<Tbl>), 1, <PartitionId> , 'SAMPLED'); 
GO 

print 'DONE: ' + CAST(GETDATE() AS NVARCHAR) 
GO 

-- show the table back to app logic 
exec sp_rename <tbl>, <tbl_orig> 
GO 
0

您可以重建分區到新的文件組。這將導致完美連續的頁面和完美填充的文件。這通常是一種非常好的碎片整理方式。您可以自動執行此操作。

通過重建進行碎片整理存在一些問題,因爲您發現了這些問題。您需要大量的臨時空間,並且您新分配的B樹將被SQL Server分配算法壓縮成大量空閒空間。分配算法不聰明。它不會嘗試找到大洞。如果它們存在,很高興將新樹散佈在小孔上。這就是你在重建後可能直接被分割的原因。 (有趣的是,NTFS有相同的問題,如果你只是順序地寫一個100GB的文件,它可能會變得非常分散。)

我相信這個問題在SQL Server社區中沒有被廣泛理解。

相關問題