Advertisement
Guest User

Untitled

a guest
Jun 13th, 2019
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PL/SQL 3.71 KB | None | 0 0
  1. USE [] -- устанавливаем текущую базу
  2. SET NOCOUNT ON; -- отключаем вывод количества возвращаемых строк, это несколько ускорит обработку
  3. DECLARE @objectid int; -- ID объекта
  4. DECLARE @indexid int; -- ID индекса
  5. DECLARE @partitioncount bigint; -- количество секций если индекс секционирован
  6. DECLARE @schemaname nvarchar(130); -- имя схемы в которой находится таблица
  7. DECLARE @objectname nvarchar(130); -- имя таблицы
  8. DECLARE @indexname nvarchar(130); -- имя индекса
  9. DECLARE @partitionnum bigint; -- номер секции
  10. DECLARE @frag FLOAT; -- процент фрагментации индекса
  11. DECLARE @command nvarchar(4000); -- инструкция T-SQL для дефрагментации либо ренидексации
  12.  
  13. -- Отбор таблиц и индексов с помощью системного представления sys.dm_db_index_physical_stats
  14. -- Отбор только тех объектов которые являются индексами (index_id > 0),
  15. -- фрагментация которых более 10% и количество страниц в индексе более 128
  16. SELECT
  17.     object_id AS objectid,
  18.     index_id AS indexid,
  19.     partition_number AS partitionnum,
  20.     avg_fragmentation_in_percent AS frag
  21. INTO #work_to_do
  22. FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, 'LIMITED')
  23. WHERE avg_fragmentation_in_percent > 10.0 AND index_id > 0 AND page_count > 128;
  24.  
  25. -- Объявление курсора для чтения секций
  26. DECLARE partitions CURSOR FOR SELECT * FROM #work_to_do;
  27.  
  28. -- Открытие курсора
  29. OPEN partitions;
  30.  
  31. -- Цикл по секциям
  32. WHILE (1=1)
  33.     BEGIN;
  34.         FETCH NEXT
  35.            FROM partitions
  36.            INTO @objectid, @indexid, @partitionnum, @frag;
  37.         IF @@FETCH_STATUS < 0 BREAK;
  38.  
  39. -- Собираем имена объектов по ID  
  40.         SELECT @objectname = QUOTENAME(o.name), @schemaname = QUOTENAME(s.name)
  41.         FROM sys.objects AS o
  42.         JOIN sys.schemas AS s ON s.schema_id = o.schema_id
  43.         WHERE o.object_id = @objectid;
  44.         SELECT @indexname = QUOTENAME(name)
  45.         FROM sys.indexes
  46.         WHERE  object_id = @objectid AND index_id = @indexid;
  47.         SELECT @partitioncount = COUNT (*)
  48.         FROM sys.partitions
  49.         WHERE object_id = @objectid AND index_id = @indexid;
  50.  
  51. -- Если фрагментация менее или равна 30% тогда дефрагментация, иначе реиндексация
  52.         IF @frag <= 30.0
  53.             SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REORGANIZE';
  54.         IF @frag > 30.0
  55.             SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REBUILD';
  56.         IF @partitioncount > 1
  57.             SET @command = @command + N' PARTITION=' + CAST(@partitionnum AS nvarchar(10));
  58.    
  59. -- Если реиндексация, то для ускорения добавляем параметры использования TEMPDB(имеет смысл только если TempDB на отдельном физ. диске) и многопроцессорной обработки
  60.    IF @frag > 30.0
  61.    SET @command = @command + N' WITH (SORT_IN_TEMPDB = ON, MAXDOP = 0)';
  62.         EXEC (@command);
  63.         PRINT N'Executed: ' + @command;
  64.     END;
  65.  
  66. -- Закрытие курсора
  67. CLOSE partitions;
  68. DEALLOCATE partitions;
  69.  
  70. -- Удаление временной таблицы
  71. DROP TABLE #work_to_do;
  72. GO
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement