禁用并重新启用SQL Server数据库中的所有索引

时间:2013-08-14 15:33:37

标签: sql-server sql-server-2005

我正在运行DTS来在我的数据库中执行任务,首先我需要在数据库中禁用所有索引,并在DTS完成其工作时重新启用它们。

有没有办法可以禁用整个数据库中的所有索引,然后重新启用它们?

我知道如何逐个停用/启用,有人可以帮助我在DTS中立即禁用/启用所有

7 个答案:

答案 0 :(得分:32)

这是一个脚本,它将为数据库中的所有非聚簇索引输出ALTER语句。您可以轻松地修改它以输出聚簇索引的REBUILD脚本和脚本

select 'ALTER INDEX ' + I.name + ' ON ' + T.name + ' DISABLE' 
from sys.indexes I
inner join sys.tables T on I.object_id = T.object_id
where I.type_desc = 'NONCLUSTERED'
and I.name is not null

答案 1 :(得分:25)

这适用于SQL Server 2008及更新版本。它允许不同的模式以及具有空格,短划线和必须引用的其他特殊字符的名称。 What is the use of the square brackets [] in sql statements?

这些脚本会将代码输出到结果选项卡中。您必须复制/粘贴到查询选项卡并执行它们。

禁用脚本

SELECT 'ALTER INDEX ' + QUOTENAME(I.name) + ' ON ' +  QUOTENAME(SCHEMA_NAME(T.schema_id))+'.'+ QUOTENAME(T.name) + ' DISABLE' 
FROM sys.indexes I
INNER JOIN sys.tables T ON I.object_id = T.object_id
WHERE I.type_desc = 'NONCLUSTERED'
AND I.name IS NOT NULL
AND I.is_disabled = 0

启用脚本(重建)

SELECT 'ALTER INDEX ' + QUOTENAME(I.name) + ' ON ' +  QUOTENAME(SCHEMA_NAME(T.schema_id))+'.'+ QUOTENAME(T.name) + ' REBUILD' 
FROM sys.indexes I
INNER JOIN sys.tables T ON I.object_id = T.object_id
WHERE I.type_desc = 'NONCLUSTERED'
AND I.name IS NOT NULL
AND I.is_disabled = 1

这是基于另一个答案。

答案 2 :(得分:20)

我们可以使用下面的脚本来禁用索引

ALTER INDEX ALL ON [TableName]
DISABLE;

批量插入表格,然后在脚本下方运行。

ALTER INDEX ALL ON [TableName]
REBUILD;

答案 3 :(得分:5)

要启用索引,您必须重建它。此脚本将重建所有已禁用的索引。

DECLARE @my_sql2 NVARCHAR(200);

DECLARE cur_rebuild CURSOR FOR 
   SELECT 'ALTER INDEX ' +  i.name + ' ON ' + t.name + ' REBUILD' FROM sys.indexes i JOIN sys.tables t ON i.object_id = t.object_id WHERE i.is_disabled = 1 ORDER BY t.name, i.name;
OPEN cur_rebuild;
FETCH NEXT FROM cur_rebuild INTO @my_sql2;
WHILE @@FETCH_STATUS = 0
   BEGIN
      EXECUTE sp_executesql  @my_sql2;
      FETCH NEXT FROM cur_rebuild INTO @my_sql2;
   END;
CLOSE cur_rebuild;
DEALLOCATE cur_rebuild;
GO

答案 4 :(得分:3)

您必须运行一个脚本,为表和索引选择元数据。然后你可以做:

ALTER INDEX indexname ON tablename DISABLE; 

稍后您可以运行类似的脚本来重建:

ALTER INDEX indexname ON tablename REBUILD; 

您可以一次执行这些操作,或将它们收集到NVARCHAR(MAX)变量中并作为单个批处理执行。您可以在之前的问题中看到示例代码:

Disable all non-clustered indexes

答案 5 :(得分:2)

在加载大量数据时禁用索引是个好主意,但是...最大的问题是聚簇索引。如果禁用聚簇索引,则表示已禁用整个表。

有几个选项表明自己,而且没有一个是简单的。

1)循环遍历系统视图(sys.indexes),提取表和索引名称,生成并执行动态SQL以禁用索引。有一个“撤消”例程来重新启用它们。 (要小心 - 它是唯一索引还是唯一约束?)唉,只有在不使用聚簇索引时才有效。祝你好运。

2)对于1,但跳过任何聚簇索引。加载数据时,请确保它以(聚簇索引)顺序加载,否则加载时间和碎片表都会很差。 (如果您的数据提供者与我的一样,那么也祝好运。)

3)在数据库中创建包含“加载”表中索引定义的表。构建循环遍历它们的例程并删除所有索引(聚簇索引最后)。如果先截断表格,这将很快。加载数据,然后循环并从头开始重新创建索引(首先是群集)。使用表分区可以减少系统其余部分的负担(例如,在“加载”表上执行以上所有操作,然后使用分区切换将加载的数据移动到“实时”表中)。我花了不少时间来构建这样一个系统,但它可以而且可以工作。

答案 6 :(得分:0)

使用此脚本禁用所有索引

-- Disable All Indices
DECLARE @Script NVARCHAR(MAX)
DECLARE curIndices CURSOR FAST_FORWARD READ_ONLY FOR
    SELECT 'ALTER INDEX ' + QUOTENAME(indices.name) + ' ON ' + QUOTENAME(SCHEMA_NAME(tableNames.schema_id))+'.'+ QUOTENAME(tableNames.name) + ' DISABLE'
    FROM
        sys.indexes indices  INNER JOIN 
        sys.tables tableNames ON indices.object_id = tableNames.object_id
    WHERE 
        indices.type_desc = 'NONCLUSTERED' AND 
        indices.name IS NOT NULL AND
        indices.is_disabled = 0;
OPEN curIndices
FETCH NEXT FROM curIndices INTO @Script
WHILE @@FETCH_STATUS = 0
BEGIN
    PRINT @Script
    EXECUTE sp_executesql @Script 

    FETCH NEXT FROM curIndices INTO @Script
END
CLOSE curIndices
DEALLOCATE curIndices

使用此脚本重建(启用)所有索引

-- Rebuild All Indices
DECLARE @Script NVARCHAR(MAX)
DECLARE curIndices CURSOR FAST_FORWARD READ_ONLY FOR
    SELECT 'ALTER INDEX ' + QUOTENAME(indices.name) + ' ON ' + QUOTENAME(SCHEMA_NAME(tableNames.schema_id))+'.'+ QUOTENAME(tableNames.name) + ' REBUILD'
    FROM
        sys.indexes indices  INNER JOIN 
        sys.tables tableNames ON indices.object_id = tableNames.object_id
    WHERE 
        indices.type_desc = 'NONCLUSTERED' AND 
        indices.name IS NOT NULL AND
        indices.is_disabled = 1;
OPEN curIndices
FETCH NEXT FROM curIndices INTO @Script
WHILE @@FETCH_STATUS = 0
BEGIN
    PRINT @Script
    EXECUTE sp_executesql @Script 

    FETCH NEXT FROM curIndices INTO @Script
END
CLOSE curIndices
DEALLOCATE curIndices