如何检查我是否可以从SQL Server中的DB中删除索引

时间:2011-04-05 13:09:09

标签: sql sql-server-2005 indexing

在对DB进行大量重新设计之后,我需要从中删除所有索引,并设置新的索引 我找到了很好的scrpipt获取所有索引并删除但我有问题 - 我无法删除由PRIMARY KEY约束创建的索引。 (也许还有其他类型的索引我无法删除)。

我的问题是:如何更改下面的代码以删除除主键创建的索引之外的所有索引或我无法手动删除的其他索引。

DECLARE @indexName VARCHAR(128)
DECLARE @tableName VARCHAR(128)

DECLARE [indexes] CURSOR FOR
    SELECT  [sysindexes].[name] AS [Index], [sysobjects].[name] AS [Table]
    FROM [sysindexes]
    INNER JOIN [sysobjects] ON [sysindexes].[id] = [sysobjects].[id]    
    WHERE [sysindexes].[name] IS NOT NULL AND [sysobjects].[type] = 'U'

OPEN [indexes]

FETCH NEXT FROM [indexes] INTO @indexName, @tableName
WHILE @@FETCH_STATUS = 0
BEGIN
    EXEC ('DROP INDEX [' + @indexName + '] ON [' + @tableName + ']')
    FETCH NEXT FROM [indexes] INTO @indexName, @tableName
END

CLOSE [indexes]
DEALLOCATE [indexes]

2 个答案:

答案 0 :(得分:5)

您可以尝试使用sys.indexes目录视图而不是已弃用的sysindexes

该目录视图具有列调用is_primary_key,因此您应该能够找到所有非主键索引,如下所示:

SELECT *
FROM sys.indexes
WHERE is_primary_key = 0

您可以通过以下方式轻松创建DROP INDEX语句:

SELECT 'DROP INDEX ' + name + ' ON ' + object_name(object_id)
FROM sys.indexes
WHERE is_primary_key = 0
AND object_ID > 255     -- exclude system-level tables with object_id <= 255
AND name IS NOT NULL    -- exclude heaps with a NULL index name

只需复制并粘贴此语句的输出,然后运行 ​​- 您应该完成。

答案 1 :(得分:1)

根据Marc_s的回答,我找到了正确的脚本版本:

SELECT 'DROP INDEX ' + name + ' ON ' + object_name(object_id)
FROM sys.indexes
WHERE is_primary_key = 0 AND is_unique_constraint = 0
AND OBJECTPROPERTY(object_id, 'IsMSShipped') = 0     -- exclude system-level tables
AND name IS NOT NULL

检查object_Id是否大于255是不够的:
  - 我们不得不使用OBJECTPROPERTY(object_id,'IsMSShipped')= 0,因为像queue_messages这样的系统表具有很高的id   - 我们还必须检查索引是否由唯一约束创建:is_unique_constraint = 0

完成这些改进之后,它将删除用户创建的所有索引。