我使用以下内容从我的数据库中选择了许多非聚集索引:
SELECT sys.objects.name tableName,
sys.indexes.name indexName
FROM sys.indexes
JOIN sys.objects ON sys.indexes.object_id = sys.objects.object_id
WHERE sys.indexes.type_desc = 'NONCLUSTERED'
AND sys.objects.type_desc = 'USER_TABLE'
我想在每个结果上运行以下内容:
ALTER INDEX indexName ON tableName DISABLE
我该怎么做呢?还有更好的方法吗?
修改
我这样做是为了截断表,然后用“ALTER INDEX bla ON table REBUILD”重建。这需要自动化,因此丢弃和重建将是一个更高的维护活动,我宁愿避免。这是一个糟糕的计划吗?我需要一种以最小的开销清空表的方法。
答案 0 :(得分:31)
您可以将查询构建到select语句中,如下所示:
DECLARE @sql AS VARCHAR(MAX)='';
SELECT @sql = @sql +
'ALTER INDEX ' + sys.indexes.name + ' ON ' + sys.objects.name + ' DISABLE;' +CHAR(13)+CHAR(10)
FROM
sys.indexes
JOIN
sys.objects
ON sys.indexes.object_id = sys.objects.object_id
WHERE sys.indexes.type_desc = 'NONCLUSTERED'
AND sys.objects.type_desc = 'USER_TABLE';
EXEC(@sql);
第13章和第10章是换行/回车,因此您可以将EXEC
替换为PRINT
来检查输出,并且它更具可读性。
答案 1 :(得分:3)
使用索引和表名构建表变量。使用循环迭代它们,并为每个循环执行动态SQL语句。
declare @Indexes table
(
Num int identity(1,1) primary key clustered,
TableName nvarchar(255),
IndexName nvarchar(255)
)
INSERT INTO @Indexes
(
TableName,
IndexName
)
SELECT sys.objects.name tableName,
sys.indexes.name indexName
FROM sys.indexes
JOIN sys.objects ON sys.indexes.object_id = sys.objects.object_id
WHERE sys.indexes.type_desc = 'NONCLUSTERED'
AND sys.objects.type_desc = 'USER_TABLE'
DECLARE @Max INT
SET @Max = @@ROWCOUNT
SELECT @Max as 'max'
SELECT * FROM @Indexes
DECLARE @I INT
SET @I = 1
DECLARE @TblName NVARCHAR(255), @IdxName NVARCHAR(255)
DECLARE @SQL NVARCHAR(MAX)
WHILE @I <= @Max
BEGIN
SELECT @TblName = TableName, @IdxName = IndexName FROM @Indexes WHERE Num = @I
SELECT @SQL = N'ALTER INDEX ' + @IdxName + N' ON ' + @TblName + ' DISABLE;'
EXEC sp_sqlexec @SQL
SET @I = @I + 1
END
答案 2 :(得分:0)
当然我们有单独的脚本,因为一旦删除它们,索引就不再存在于系统表中。
答案 3 :(得分:0)
使用游标编写脚本比临时表更简洁(并且稍微简短)。要重新启用索引,请将DISABLE替换为REBUILD。
DECLARE cur_indexes CURSOR FOR
SELECT sys.objects.name tableName,
sys.indexes.name indexName
FROM sys.indexes
JOIN sys.objects ON sys.indexes.object_id = sys.objects.object_id
WHERE sys.indexes.type_desc = 'NONCLUSTERED'
AND sys.objects.type_desc = 'USER_TABLE'
DECLARE @TblName NVARCHAR(255), @IdxName NVARCHAR(255)
DECLARE @SQL NVARCHAR(MAX)
open cur_indexes
fetch next from cur_indexes into @TblName, @IdxName
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @SQL = N'ALTER INDEX ' + @IdxName + N' ON ' + @TblName + ' DISABLE;'
EXEC sp_sqlexec @SQL
fetch next from cur_indexes into @TblName, @IdxName
END
close cur_indexes
deallocate cur_indexes
答案 4 :(得分:0)
仅禁用唯一的非聚集索引
DECLARE @EnableOrRebuild as nvarchar(20)
SET @EnableOrRebuild = 'DISABLE'
/* SET @EnableOrRebuild = 'REBUILD' */ -- Uncomment for REBUILD
DECLARE @TableName as nvarchar(200) = 'ChorusDestinataire' -- Enter your table name here
DECLARE @SchemaName as nvarchar(200) = 'dbo' -- Enter the schema here
DECLARE @Sql as nvarchar(2000)=''
SELECT @Sql = @Sql + N'ALTER INDEX ' + quotename(i.name) + N' ON ' + quotename(s.name) + '.' + quotename(o.name) + ' ' + @EnableOrRebuild + N';' + CHAR(13) + CHAR(10)
FROM sys.indexes i
INNER JOIN sys.objects o ON i.object_id = o.object_id
INNER JOIN sys.schemas s ON s.schema_id = o.schema_id
WHERE i.type_desc = N'NONCLUSTERED'
AND i.ignore_dup_key = 1
AND o.type_desc = N'USER_TABLE'
AND o.name = @TableName
AND s.name = @SchemaName
-- SELECT @Sql;
EXEC (@Sql);