Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Автоматизиране на повторното изграждане на INDEX въз основа на резултатите от фрагментацията?

Използвам този скрипт. Моля, имайте предвид, че бих ви посъветвал да прочетете за dmv, който използвам тук, те са скрит скъпоценен камък в SQL2005+.

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
CREATE TABLE #FragmentedIndexes
(
 DatabaseName SYSNAME
 , SchemaName SYSNAME
 , TableName SYSNAME
 , IndexName SYSNAME
 , [Fragmentation%] FLOAT
)

INSERT INTO #FragmentedIndexes
SELECT
 DB_NAME(DB_ID()) AS DatabaseName
 , ss.name AS SchemaName
 , OBJECT_NAME (s.object_id) AS TableName
 , i.name AS IndexName
 , s.avg_fragmentation_in_percent AS [Fragmentation%]
FROM sys.dm_db_index_physical_stats(db_id(),NULL, NULL, NULL, 'SAMPLED') s
INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id]
AND s.index_id = i.index_id
INNER JOIN sys.objects o ON s.object_id = o.object_id
INNER JOIN sys.schemas ss ON ss.[schema_id] = o.[schema_id]
WHERE s.database_id = DB_ID()
AND i.index_id != 0
AND s.record_count > 0
AND o.is_ms_shipped = 0
DECLARE @RebuildIndexesSQL NVARCHAR(MAX)
SET @RebuildIndexesSQL = ''
SELECT
 @RebuildIndexesSQL = @RebuildIndexesSQL +
CASE
 WHEN [Fragmentation%] > 30
   THEN CHAR(10) + 'ALTER INDEX ' + QUOTENAME(IndexName) + ' ON '
      + QUOTENAME(SchemaName) + '.'
      + QUOTENAME(TableName) + ' REBUILD;'
 WHEN [Fragmentation%] > 10
    THEN CHAR(10) + 'ALTER INDEX ' + QUOTENAME(IndexName) + ' ON '
    + QUOTENAME(SchemaName) + '.'
    + QUOTENAME(TableName) + ' REORGANIZE;'
END
FROM #FragmentedIndexes
WHERE [Fragmentation%] > 10
DECLARE @StartOffset INT
DECLARE @Length INT
SET @StartOffset = 0
SET @Length = 4000
WHILE (@StartOffset < LEN(@RebuildIndexesSQL))
BEGIN
 PRINT SUBSTRING(@RebuildIndexesSQL, @StartOffset, @Length)
 SET @StartOffset = @StartOffset + @Length
END
PRINT SUBSTRING(@RebuildIndexesSQL, @StartOffset, @Length)
EXECUTE sp_executesql @RebuildIndexesSQL
DROP TABLE #FragmentedIndexes

Също така имайте предвид, че този скрипт може да работи известно време и да блокира достъпа до вашите таблици. Освен ако нямате издания на Enterprise, SQL може да ЗАКЛЮЧИ таблицата при повторно изграждане на индекса. Това ще блокира всички заявки към тази таблица, използващи индекса, докато дефрагментирането на индекса приключи. Поради това не се препоръчва да стартирате повторно изграждане на индекса по време на работни часове само по време на прозорци за поддръжка. Ако използвате корпоративно издание, можете да използвате опцията ONLINE=ON за дефрагментиране на индекси онлайн. Това ще използва повече място, но вашите таблици няма да бъдат блокирани/заключени по време на операцията по дефрагментиране.

Извикайте, ако имате нужда от повече информация.

АКТУАЛИЗИРАНО:

Ако изпълнявате тази заявка в по-малка база данни, вероятно можете да използвате параметъра „DETAILED“ в извикването на sys.dm_db_index_physical_stats. Това вероятно е по-подробно разглеждане на индексите. Дискусията в коментарите също така ще посочи, че на много по-големи таблици вероятно си струва да направите SAMPLED сканиране, тъй като това ще помогне за намаляване на времето, необходимо за сканиране на индекса.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Използване на транзакция ROLLBACK в SQL Server

  2. Винаги ли вмъкнатите записи получават непрекъснати стойности за самоличност

  3. T-sql, отметки, клеймо за време

  4. Вмъкване на брой празни редове в SQL

  5. Посочената схема не е валидна. Грешки:Няколко типа с името