How can I drop all indexes in a SQL database with one command?

前端 未结 7 1413
温柔的废话
温柔的废话 2021-02-04 00:01

So, how can I drop all indexes in a SQL database with one command? I have this command that will get me all the 20 or so drop statements, but how can I run all of those drop s

7条回答
  •  臣服心动
    2021-02-04 00:55

    The "Final Draft" that OP posts as part of his question errors out if there are already zero indexes on any table in the DB. I needed to fix that.

    Also, I wanted more control over the process than dropping all indexes on all tables, so I wrote the following stored proc to do it one table at a time:

    CREATE PROCEDURE [dbo].[sp_DropAllIndexesOnTable]
    
    @TableName varchar(1000)
    
    AS
    BEGIN
    SET NOCOUNT ON;
    
       DECLARE @DropCommand1 nvarchar(4000)
       DECLARE @DropCommand2 nvarchar(4000)
    
    --Create Temp Table to hold the names and table names of all Clustered Indexes
        SELECT o.name AS TableName, i.name AS IndexName
          INTO #AllClustered
          FROM sys.indexes i 
    INNER JOIN sys.objects o ON i.object_id=o.object_id
         WHERE o.type <> 'S'
           AND is_primary_key = 1
    
    --Create Temp Table to hold the names and table names of all NonClustered Indexes
        SELECT o.name AS TableName, i.name AS IndexName
          INTO #AllNonClustered
          FROM sys.indexes i 
    INNER JOIN sys.objects o ON i.object_id=o.object_id
         WHERE o.type <> 'S'
           AND is_primary_key <> 1 
           AND index_id > 0
    
    --Create DROP CONSTRAINT command for the Primary Key Constraint if there is one
        SELECT @DropCommand1 = ( SELECT 'ALTER TABLE dbo.['+ TableName +'] DROP CONSTRAINT ['+ IndexName +'];'
                                   FROM #AllClustered
                                  WHERE TableName = @TableName
                                    FOR xml path('') ); 
    
    --Create DROP INDEX command for the indexes on the table if there are any 
        SELECT @DropCommand2 = ( SELECT 'DROP INDEX [' + IndexName + '] ON dbo.['+ TableName +'];'
                                   FROM #AllNonClustered
                                  WHERE TableName = @TableName
                                    FOR xml path('') );
    
            IF (@DropCommand1 IS NULL AND @DropCommand2 IS NULL) PRINT 'No action taken, zero indexes found on table ' + @TableName
            IF @DropCommand1 IS NOT NULL EXEC sp_executesql @DropCommand1
            IF @DropCommand2 IS NOT NULL EXEC sp_executesql @DropCommand2
    
    DROP TABLE IF EXISTS #AllClustered
    DROP TABLE IF EXISTS #AllNonClustered
    
    END
    GO
    

    I cycle through the specific tables in my DB which I want to drop indexes on using a loop, and I drop the indexes by calling this proc with the table name, and recreate better ones right after. This way, only one table at a time has no indexes.

    The reason I do this and the number of tables I do it on would make your head spin, but I definitely needed a proc like this!

提交回复
热议问题