6

I have a mssql database, we'll call it: mssqlDB01. I've been tasked with performing defragmentation on all of the tables. This database has a few hundred tables and each table has a range of 1 to 15 indexes per table.


Google led me to discover a practice to defrag all indexes per table, but I can't figure out how to do it on all tables.

ALTER INDEX ALL ON TABLENAME REBUILD;

what i'm looking for is

ALTER INDEX ALL ON * REBUILD; 

but it complains

Msg 102, Level 15, State 1, Line 2
Incorrect syntax near '*'.`

below lets me find all tables in my DB

SELECT * FROM information_schema.tables WHERE TABLE_TYPE='BASE TABLE'

can I somehow push this into the command?

ALTER INDEX ALL ON (SELECT * FROM information_schema.tables WHERE TABLE_TYPE='BASE TABLE'; ) REBUILD;
  • EXEC sp_MSforeachtable @command1="print '?' DBCC DBREINDEX ('?', ' ', 80)" – StingyJack Jan 21 '19 at 11:48
11

You could probably write a script that uses dynamic SQL to do that, but why do that when you can use someone else's? Ola Hallengren's are the best known and free, but Minion Ware also has a free reindex script.

If you insist on writing it yourself, something like this might work:

Use mssqlDB01

Declare @TBname nvarchar(255),
        @SQL nvarchar(max) 


select @TBname = min(TABLE_NAME) from INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE'

while @TBname is not null

BEGIN
    set @SQL='ALTER INDEX ALL ON [' + @TBname + '] REBUILD;'
    --print @SQL
    EXEC SP_EXECUTESQL @SQL
    select @TBname = min(TABLE_NAME) from INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' and TABLE_NAME > @TBname          
END
|improve this answer|||||
3
  1. Press Ctrl + T
  2. Run this query:

    SELECT 'ALTER INDEX ALL ON ' + table_name + '  REBUILD;' 
        FROM Information_Schema.tables where  table_type ='BASE TABLE'
    
  3. Copy the output and paste it into the SQL window, then click on run.

|improve this answer|||||
1

Building on @Firdaus nice and simple answer:

If your database has schemas, try running the following in SSMS:

SELECT 'ALTER INDEX ALL ON ' + TABLE_SCHEMA + '.' + table_name + '  REBUILD;' 
    FROM Information_Schema.tables where  table_type ='BASE TABLE'
|improve this answer|||||
0

This will rebuild the indexes and keep the compression settings if you have any:

DECLARE
    @schemaName sysname,
    @tableName sysname,
    @compressionType VARCHAR(50),
    @sql NVARCHAR(1000)

DECLARE table_cursor CURSOR FAST_FORWARD
FOR
SELECT
    SCHEMA_NAME(t.schema_id) AS SchemaName,
    t.name AS TableName,
    p.data_compression_desc AS CompressionType
FROM
    sys.partitions AS p
    INNER JOIN sys.tables AS t ON t.object_id = p.object_id
WHERE
    p.index_id IN (0, 1)

OPEN table_cursor

FETCH NEXT FROM table_cursor
INTO @schemaName, @tableName, @compressionType

WHILE @@FETCH_STATUS = 0
BEGIN
    SET @sql = 'ALTER INDEX ALL ON [' + @schemaName + '].[' + @tableName + '] REBUILD'
        + CASE WHEN @compressionType <> 'NONE' 
            THEN ' PARTITION = ALL WITH(DATA_COMPRESSION = ' + @compressionType + ')'
            ELSE ''
          END

    PRINT @sql
    EXEC sys.sp_executesql @SQL

    FETCH NEXT FROM table_cursor   
    INTO @schemaName, @tableName, @compressionType
END

CLOSE table_cursor;  
DEALLOCATE table_cursor;  
|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.