Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rebuild all indexes in a Database

I have a very large SQL Server 2008 R2 database (1.5TB) and will be copying some data from column to column within the same table. I've been told that the schema has a large number of indexes and was wondering if there is a default query or script that will rebuild all the indexes. Have also been advised to update the statistics at the same time?

Each of the 30 tables has one clustered index and 13x non-clustered indexes

Thanks.

like image 747
ChrisD Avatar asked Sep 10 '15 15:09

ChrisD


People also ask

What does rebuild indexing do?

They speed up the querying process, but indexes typically become fragmented over time, and highly fragmented indexes result in slow query performance and can cause your application to respond slowly. An index rebuild creates a brand new structure for the index.

Should you rebuild indexes?

Estimates suggest that anywhere from 5 to 30 percent of indexes should be reorganized at any given time, while a full 30 percent should be rebuilt, due to fragmentation. Reorganizing the database is a relatively fast process; however, it does not fix everything.

Does rebuilding indexes improve performance?

Reorganizing a columnstore index may require additional CPU resources to compress data, which may slow the overall system performance while the operation is running. However, once data is compressed, query performance improves.

Which command is used to rebuild indexes?

The rebuildIndices command is used to rebuild database indexes in the event of them becoming fragmented.


2 Answers

Try the following script:

Exec sp_msforeachtable 'SET QUOTED_IDENTIFIER ON; ALTER INDEX ALL ON ? REBUILD' GO 

Also

I prefer(After a long search) to use the following script, it contains @fillfactor determines how much percentage of the space on each leaf-level page is filled with data.

DECLARE @TableName VARCHAR(255) DECLARE @sql NVARCHAR(500) DECLARE @fillfactor INT SET @fillfactor = 80  DECLARE TableCursor CURSOR FOR SELECT QUOTENAME(OBJECT_SCHEMA_NAME([object_id]))+'.' + QUOTENAME(name) AS TableName FROM sys.tables OPEN TableCursor FETCH NEXT FROM TableCursor INTO @TableName WHILE @@FETCH_STATUS = 0 BEGIN SET @sql = 'ALTER INDEX ALL ON ' + @TableName + ' REBUILD WITH (FILLFACTOR = ' + CONVERT(VARCHAR(3),@fillfactor) + ')' EXEC (@sql) FETCH NEXT FROM TableCursor INTO @TableName END CLOSE TableCursor DEALLOCATE TableCursor GO 

for more info, check the following link:

https://blog.sqlauthority.com/2009/01/30/sql-server-2008-2005-rebuild-every-index-of-all-tables-of-database-rebuild-index-with-fillfactor/

and if you want to Check Index Fragmentation on Indexes in a Database, try the following script:

SELECT dbschemas.[name] as 'Schema', dbtables.[name] as 'Table', dbindexes.[name] as 'Index', indexstats.avg_fragmentation_in_percent, indexstats.page_count FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL, NULL, NULL) AS indexstats INNER JOIN sys.tables dbtables on dbtables.[object_id] = indexstats.[object_id] INNER JOIN sys.schemas dbschemas on dbtables.[schema_id] = dbschemas.[schema_id] INNER JOIN sys.indexes AS dbindexes ON dbindexes.[object_id] = indexstats.[object_id] AND indexstats.index_id = dbindexes.index_id WHERE indexstats.database_id = DB_ID() AND dbtables.[name] like '%%' ORDER BY indexstats.avg_fragmentation_in_percent desc 

For more information, Check the following link:

http://www.schneider-electric.com/en/faqs/FA234246/

like image 51
Mohamad Mahmoud Avatar answered Sep 22 '22 00:09

Mohamad Mahmoud


Replace the "YOUR DATABASE NAME" in the query below.

    DECLARE @Database NVARCHAR(255)        DECLARE @Table NVARCHAR(255)       DECLARE @cmd NVARCHAR(1000)        DECLARE DatabaseCursor CURSOR READ_ONLY FOR       SELECT name FROM master.sys.databases        WHERE name IN ('YOUR DATABASE NAME')  -- databases     AND state = 0 -- database is online     AND is_in_standby = 0 -- database is not read only for log shipping     ORDER BY 1        OPEN DatabaseCursor        FETCH NEXT FROM DatabaseCursor INTO @Database       WHILE @@FETCH_STATUS = 0       BEGIN           SET @cmd = 'DECLARE TableCursor CURSOR READ_ONLY FOR SELECT ''['' + table_catalog + ''].['' + table_schema + ''].['' +          table_name + '']'' as tableName FROM [' + @Database + '].INFORMATION_SCHEMA.TABLES WHERE table_type = ''BASE TABLE'''            -- create table cursor          EXEC (@cmd)          OPEN TableCursor            FETCH NEXT FROM TableCursor INTO @Table           WHILE @@FETCH_STATUS = 0           BEGIN           BEGIN TRY                 SET @cmd = 'ALTER INDEX ALL ON ' + @Table + ' REBUILD'               PRINT @cmd -- uncomment if you want to see commands              EXEC (@cmd)            END TRY           BEGIN CATCH              PRINT '---'              PRINT @cmd              PRINT ERROR_MESSAGE()               PRINT '---'           END CATCH            FETCH NEXT FROM TableCursor INTO @Table           END            CLOSE TableCursor           DEALLOCATE TableCursor           FETCH NEXT FROM DatabaseCursor INTO @Database       END       CLOSE DatabaseCursor        DEALLOCATE DatabaseCursor 
like image 33
Hainan Zhao Avatar answered Sep 23 '22 00:09

Hainan Zhao