【问题标题】:How to check if I can remove index from DB in SQL Server如何检查我是否可以从 SQL Server 中的数据库中删除索引
【发布时间】:2011-07-29 23:15:32
【问题描述】:

对数据库进行大规模重新设计后,我需要从中删除所有索引,并设置新索引。
我找到了很好的脚本来获取所有索引并删除,但我有问题 - 我无法删除由 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]

【问题讨论】:

    标签: sql sql-server-2005 indexing


    【解决方案1】:

    您可以尝试使用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
    

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

    【讨论】:

    • 使用该表是一个很好的建议,谢谢 - 但运行由它生成的代码是有风险的 - 它还会从 systables 中删除索引并为 HEAP 类型的索引返回 null - 我的代码示例仅返回自定义表的索引
    • 如果您在该语句中添加AND object_ID &gt; 255 AND name IS NOT NULL,您会得到相同的结果;所有“系统级”表(id
    • 好的,谢谢 - 好多了。现在有我的索引和几个索引,例如:“queue_clustered_index” - 你知道它是什么吗?
    • @Korn - Marek K. 抱歉,我不知道或有你的数据库 - 我不能告诉你这些是什么..... DROP INDEX 语句应该列出该索引定义的表on - 看看那张桌子....
    【解决方案2】:

    根据 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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-15
      • 1970-01-01
      • 2018-05-11
      • 2020-08-16
      • 2012-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多