【问题标题】:Automatically Drop and Recreate current indexes自动删除并重新创建当前索引
【发布时间】:2012-07-02 21:23:14
【问题描述】:

我正在努力提供一种方法来允许批量更新我们的表(每次更新超过 1M 新行或更新行),并且有兴趣删除当前索引并在更新后重新创建它们。

我想知道是否有人有脚本来提供这些操作的松散耦合,以便如果索引随时间变化,更新过程不会改变。

这似乎是社区可能已经解决的问题之一。

【问题讨论】:

  • 请通过添加适当的标签(Oracle、SQL Server、MySQL 等)来指定您的目标关系数据库。 利用未被普遍支持的语言或产品特性提供答案。此外,通过使用特定的 RDBMS 对其进行标记,您的问题可能会受到更适合回答您问题的人的关注。

标签: sql sql-server-2008 etl


【解决方案1】:

我有用于查询系统表以捕获所有非聚集索引并禁用然后在完成后重建的脚本。以下是在标准版上使用,如果您是企业版,我会添加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 更改为PRINT 并查看将执行的代码并手动运行它。

排除表格的条件

AND o.name NOT IN ('tblTest','tblTest1');

【讨论】:

  • 太棒了!只是要反转 Not IN。比我尝试做的 drop 和 create 容易得多
  • 您也可以使用sys.tables 而不是sys.objects,这样您就不必一直指定WHERE o.type_desc = 'USER_TABLE' ....
【解决方案2】:
EXEC sp_MSforEachTable 'ALTER INDEX ALL ON ? DISABLE'

EXEC sp_MSforEachTable 'ALTER INDEX ALL ON ? REBUILD'

如果您想对所有表和每个索引执行此操作,您只需要这样做。

【讨论】:

  • 我遇到了问题。禁用聚集索引的表无法插入任何行,因为表被禁用。
  • INSERT INTO 在禁用聚集索引的表上失败。禁用聚集索引的表中的数据行仅可用于删除或重建操作。
  • 嗯,是的,但它对我有用。我在 5 年前回答了这个问题,但我并不是 SQL Server 方面的专家。所以我帮不了你。请提出正确的问题!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-29
  • 2013-10-18
  • 1970-01-01
  • 1970-01-01
  • 2021-08-04
  • 1970-01-01
  • 2019-11-17
相关资源
最近更新 更多