问题: 在 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
在测试环境中,这对某些分区产生了很好的结果(0% 的碎片化和保留空间上接近 0% 的“浪费”空间。考虑到下一阶段是通过线路移动数据而浪费了),但我有一个分区案例,SHRINKFILE 减少了大小显着,但会导致 99.99% 的碎片化;REBUILD 解决了碎片问题,但文件组大小加倍(一半是保留空间)——这可能是预期的,因为重建从头开始创建索引。如果我之后缩小,我可以回收空间,但会再次获得大碎片。这可以绕圈子
我现在正在尝试对缩小的文件组运行重组:
ALTER INDEX <IdxName> on <Tbl> REORGANIZE PARTITION = <PartitionId>
因为这应该有望在不增加数据文件的情况下修复索引碎片。然而:
- 在 99.99% 的碎片索引上运行 Reorganize 是个好主意吗?
- 结果会与运行重建相当/劣于/优于吗?
我正在考虑的另一个选择是将分区重建为全新的文件组,但这需要操作分区模式 - 我希望使过程尽可能简单。