我正在努力提供一种方法来允许批量更新我们的表(每次更新超过 1M 新行或更新行),并且有兴趣删除当前索引并在更新后重新创建它们。
我想知道是否有人有一个脚本来提供这些操作的松散耦合,以便如果索引随时间变化,更新过程不会改变。
看起来这是社区可能已经解决的问题之一。
我正在努力提供一种方法来允许批量更新我们的表(每次更新超过 1M 新行或更新行),并且有兴趣删除当前索引并在更新后重新创建它们。
我想知道是否有人有一个脚本来提供这些操作的松散耦合,以便如果索引随时间变化,更新过程不会改变。
看起来这是社区可能已经解决的问题之一。
我有用于查询系统表以捕获所有非聚集索引并禁用然后在完成后重建的脚本。以下适用于标准版,如果您使用的是企业版,我会添加该ONLINE
选项。
禁用
DECLARE @sql AS VARCHAR(MAX);
SET @sql = '';
SELECT
@sql = @sql + 'ALTER INDEX [' + i.name + '] ON [' + o.name + '] DISABLE; '
FROM sys.indexes AS i
JOIN sys.objects AS o ON i.object_id = o.object_id
WHERE i.type_desc = 'NONCLUSTERED'
AND o.type_desc = 'USER_TABLE'
EXEC (@sql)
重建
DECLARE @sql AS VARCHAR(MAX);
SET @sql = '';
SELECT
@sql = @sql + 'ALTER INDEX [' + i.name + '] ON [' + o.name + '] REBUILD WITH (FILLFACTOR = 80); '
FROM sys.indexes AS i
JOIN sys.objects AS o ON i.object_id = o.object_id
WHERE i.type_desc = 'NONCLUSTERED'
AND o.type_desc = 'USER_TABLE'
EXEC (@sql);
我喜欢这种方法,因为它非常可定制,因为您可以根据条件排除/包含某些表以及避免光标。您还可以将 更改EXEC
为 aPRINT
并查看将执行并手动运行它的代码。
排除表的条件
AND o.name NOT IN ('tblTest','tblTest1');
EXEC sp_MSforEachTable 'ALTER INDEX ALL ON ? DISABLE'
和
EXEC sp_MSforEachTable 'ALTER INDEX ALL ON ? REBUILD'
如果您想对所有表和每个索引执行此操作,您只需要这样做。