【问题标题】:Delete all indexes of specific database删除特定数据库的所有索引
【发布时间】:2013-02-06 23:44:16
【问题描述】:

如何从一个数据库中删除所有索引,无论是集群还是非集群?

我需要使用脚本而不是 GUI。

已编辑

数据库有 7 个表,其中一些是查找表,一些是通过外键关联的。每个表都有最小的一个索引,在创建主键时创建,因此自动创建了约束。通过 GUI 删除此类索引时,我收到一个错误,即由于依赖于其他键而无法删除索引。

所以,我需要先删除作为外键的索引键,然后在主键上创建索引。

【问题讨论】:

  • 你能解释一下你为什么要这样做吗?
  • 我有一些创建索引的示例数据库。我想创建一些使用数据库引擎优化顾问的实践,如果我有堆表,这将是一个很好的例子。因此,目的是让 Tuning Advisor 建议我在哪些对象上创建哪些索引。我想我解释得很好:)

标签: sql sql-server indexing


【解决方案1】:

动态 SQL 的变体略有不同,但是它首先删除外键,然后是主键,然后是索引(首先是非聚集索引,这样您就不会转换为堆(这会影响所有非聚集索引) )。

USE specific_database;
GO

首先,删除所有外键:

DECLARE @sql NVARCHAR(MAX);

SET @sql = N'';

SELECT @sql = @sql + N'ALTER TABLE ' 
  + QUOTENAME(OBJECT_SCHEMA_NAME([parent_object_id]))
  + '.' + QUOTENAME(OBJECT_NAME([parent_object_id])) 
  + ' DROP CONSTRAINT ' + QUOTENAME(name) + ';
'
FROM sys.foreign_keys
WHERE OBJECTPROPERTY([parent_object_id], 'IsMsShipped') = 0;

EXEC sp_executesql @sql;

现在删除主键:

DECLARE @sql NVARCHAR(MAX);

SET @sql = N'';

SELECT @sql = @sql + N'ALTER TABLE '
  + QUOTENAME(OBJECT_SCHEMA_NAME([parent_object_id]))
  + '.' + QUOTENAME(OBJECT_NAME([parent_object_id])) 
  + ' DROP CONSTRAINT ' + QUOTENAME(name) + ';
'
FROM sys.key_constraints 
WHERE [type] = 'PK'
AND OBJECTPROPERTY([parent_object_id], 'IsMsShipped') = 0;

EXEC sp_executesql @sql;

最后是索引,首先是非聚集的:

DECLARE @sql NVARCHAR(MAX);

SET @sql = N'';

SELECT @sql = @sql + N'DROP INDEX ' 
  + QUOTENAME(name) + ' ON '
  + QUOTENAME(OBJECT_SCHEMA_NAME([object_id]))
  + '.' + QUOTENAME(OBJECT_NAME([object_id])) + ';
'
FROM sys.indexes 
WHERE index_id > 0
AND OBJECTPROPERTY([object_id], 'IsMsShipped') = 0
ORDER BY [object_id], index_id DESC;

EXEC sp_executesql @sql;

请注意,数据库引擎优化顾问会推荐一堆这样的索引(根据您提供的工作负载,可能会遗漏一些,并且可能会建议冗余和几乎重复的索引)。但是,它不会推荐您刚刚删除的任何数据完整性内容(PK、FK、唯一约束)。

【讨论】:

  • 好的,这段代码将清除非聚集索引。但是在创建主键时会立即创建什么集群?由于键的依赖性,删除时是否有一些限制?
  • @veljasije 是的,没错,我认为这些只是聚集和非聚集索引,约束需要额外处理。
  • 抱歉,我没有明确提到我需要的所有东西。我会重写我的问题。
【解决方案2】:

创建一个Dynamic SQL

DECLARE @qry nvarchar(max);
SELECT @qry =  (SELECT  'DROP INDEX ' + ix.name + ' ON ' + OBJECT_NAME(ID) + '; '
                FROM  sysindexes ix
                WHERE   ix.Name IS NOT NULL AND 
                        ix.Name LIKE '%prefix_%'
                FOR XML PATH(''));
EXEC sp_executesql @qry

【讨论】:

  • 请使用sys.indexes,除非您知道 OP 正在使用 SQL Server 2000。sysindexes 最终将从产品中删除...
  • 还要注意不要使用架构前缀 - 并非所有对象都在 dbo 中,也不是每个用户的默认架构都是 dbo...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-16
  • 2013-08-19
  • 1970-01-01
  • 2014-08-15
  • 2011-11-02
  • 1970-01-01
  • 2012-03-12
相关资源
最近更新 更多