У меня есть база данных mssql, назовем ее mssqlDB01. Мне было поручено выполнить дефрагментацию всех таблиц. В этой базе данных есть несколько сотен таблиц, и каждая таблица имеет диапазон от 1 до 15 индексов на таблицу.
Google привел меня к открытию практики дефрагментации всех индексов для каждой таблицы, но я не могу понять, как это сделать для всех таблиц.
ALTER INDEX ALL ON TABLENAME REBUILD;
то, что я ищу, это
ALTER INDEX ALL ON * REBUILD;
но он жалуется
Msg 102, Level 15, State 1, Line 2
Incorrect syntax near '*'.`
ниже позволяет мне найти все таблицы в моей БД
SELECT * FROM information_schema.tables WHERE TABLE_TYPE='BASE TABLE'
могу я как-нибудь вставить это в команду?
ALTER INDEX ALL ON (SELECT * FROM information_schema.tables WHERE TABLE_TYPE='BASE TABLE'; ) REBUILD;
Вероятно, вы могли бы написать сценарий, который использует для этого динамический SQL, но зачем это делать, если вы можете использовать чужой? Ола Халленгрен самые известные и бесплатные, но Minion Ware также имеет бесплатный скрипт переиндексации..
Если вы настаиваете на написании этого самостоятельно, может сработать что-то вроде этого:
Use mssqlDB01
Declare @TBname nvarchar(255),
@schema nvarchar(255),
@SQL nvarchar(max)
select @TBname = min(TABLE_NAME) from INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE'
select @schema = SCHEMA_NAME from INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' and TABLE_NAME = @TBname
while @TBname is not null
BEGIN
set @SQL='ALTER INDEX ALL ON [' + @schema + '].[' + @TBname + '] REBUILD;'
--print @SQL
EXEC SP_EXECUTESQL @SQL
select @TBname = min(TABLE_NAME) from INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE'
select @schema = SCHEMA_NAME from INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' and TABLE_NAME = @TBname
END
Запустите этот запрос:
SELECT 'ALTER INDEX ALL ON ' + table_name + ' REBUILD;'
FROM Information_Schema.tables where table_type ='BASE TABLE'
Скопируйте вывод и вставьте его в окно SQL, затем нажмите «Выполнить».
Основываясь на приятном и простом ответе @Firdaus:
Если в вашей базе данных есть схемы, попробуйте запустить в SSMS следующее:
SELECT 'ALTER INDEX ALL ON ' + TABLE_SCHEMA + '.' + table_name + ' REBUILD;'
FROM Information_Schema.tables where table_type ='BASE TABLE'
Это восстановит индексы и сохранит настройки сжатия, если они у вас есть:
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;
Обычно администраторы баз данных создают автоматизированную функцию или имеют инструменты для восстановления индексов.
Это функциональная версия для восстановления всех индексов для всех таблиц в вашей схеме:
DECLARE @tableSchema varchar(max),
@tableName varchar(max),
@tsql nvarchar(max);
DECLARE cur CURSOR FOR SELECT TABLE_SCHEMA, TABLE_NAME FROM Information_Schema.tables where table_type ='BASE TABLE'
OPEN cur
FETCH NEXT FROM cur into @tableSchema, @tableName
WHILE @@FETCH_STATUS = 0
BEGIN
SET @tsql ='ALTER INDEX ALL ON [' + @tableSchema + '].[' + @tableName + '] REBUILD;'
PRINT(@tsql)
EXEC SP_EXECUTESQL @tsql;
FETCH NEXT FROM cur into @tableSchema, @tableName
END
CLOSE cur
DEALLOCATE cur