Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disable all non-clustered indexes

Tags:

I select a number of non-clustered indexes from my database with the following:

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'

I'd like to run the following over each of the results:

ALTER INDEX indexName ON tableName DISABLE

How would I go about doing this? Is there a better way?

EDIT

I'm doing this for the purpose of truncating tables, then rebuilding with "ALTER INDEX bla ON table REBUILD". This needs to be automated, so dropping and rebuilding would be a somewhat higher maintenance activity I'd rather avoid. Is this a bad plan? I need a means of emptying tables with minimum overhead.

like image 780
spender Avatar asked Mar 25 '10 17:03

spender


People also ask

How do I get rid of a non-clustered index?

To drop a clustered or nonclustered index, issue a DROP INDEX command. When you do this, the metadata, statistics, and index pages are removed. If you drop a clustered index, the table will become a heap. Once an index has been dropped, it can't be rebuilt – it must be created again.

Can clustered indexes be disabled?

Disabling a clustered index on a table also disables all clustered and nonclustered indexes on views that reference that table. These indexes must be rebuilt just as those on the referenced table. The data rows of the disabled clustered index cannot be accessed except to drop or rebuild the clustered index.

What is the impact of disabling an index for clustered indexes?

SQL Server Disable Index statements If you disable a clustered index of a table, you cannot access the table data using data manipulation language such as SELECT , INSERT , UPDATE , and DELETE until you rebuild or drop the index.

How do I enable and disable indexes in SQL Server?

Using SQL Server Management Studio Click the plus sign to expand the Indexes folder. Right-click the index you want to enable and select Rebuild. In the Rebuild Indexes dialog box, verify that the correct index is in the Indexes to rebuild grid and click OK.


2 Answers

You can build the queries into a select statement, like so:

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);

Chars 13 and 10 are the line-feed/carriage-returns, so you can check the output by replacing EXEC with PRINT, and it will be more readable.

like image 108
Daniel Quinlan Avatar answered Sep 21 '22 06:09

Daniel Quinlan


Build a table variable with the indexes and table names. Use a loop to iterate over them, and execute a dynamic SQL statement for each of them.

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
like image 26
Paul Williams Avatar answered Sep 22 '22 06:09

Paul Williams