V minulém článku (viz. Fragmentace indexů) jsem popisoval, jak zjistit fragmentaci indexů přes skript využívající systémové tabulky. Podle doporučení Microsoftu bychom měli indexy s fragmentací mezi 5 – 30 % reorganizovat (REORGANIZE) a indexy nad 30 % rebuildovat (REBUILD). Využijeme zde skript z minulého článku a vytvoříme automatický skript. Oprava sql indexů provedená tímto způsobem je jednoduchá a rychlá.

Automatická oprava indexů pomocí skriptu v SQL Server

Skript funguje následovně:

  • Založíme si přípravnou tabulku @TablesToMaintenance
  • Do tabulky si připravíme indexy, které budeme opravovat, tzn. všechny indexy, které mají fragmentaci > než 5 %. Doplníme si také operaci, kterou budeme provážet (REBUILD vs REORGANIZE)
  • Na konci s použitím kurzoru provedeme požadovanou operaci postupně nad každým indexem (pouštíme dynamický SQL dotaz)

DECLARE @TablesToMaintenance AS TABLE
(
  DB_Schema VARCHAR(255),
  DB_Table VARCHAR(255),
  DB_Index VARCHAR(255),
  INDEX_Fragmentation FLOAT,
  OperationToMaintenance VARCHAR(255)
)
-----------Příprava fragmentovaných tabulek----
INSERT INTO @TablesToMaintenance(
  DB_Schema,
  DB_Table,
  DB_Index,
  INDEX_Fragmentation,
  OperationToMaintenance
)
SELECT
   sch.name AS DB_Schema,
   obj.name AS DB_Table,
   ind.name AS DB_Index,
   stat.avg_fragmentation_in_percent AS INDEX_Fragmentation,
   CASE
     WHEN avg_fragmentation_in_percent between 5 and 30 THEN 'REORGANIZE'
     WHEN avg_fragmentation_in_percent >30 THEN 'REBUILD'
   END AS OperationToMaintenance
FROM
   sys.objects obj
   LEFT JOIN sys.schemas sch
     ON obj.schema_id= sch.schema_id
   LEFT JOIN sys.indexes ind
     ON obj.object_id=ind.object_id
   LEFT JOIN sys.dm_db_index_physical_stats (db_id(), NULL, NULL, NULL, 'LIMITED') AS stat
     ON ind.object_id=stat.object_id
     AND ind.index_id=stat.index_id
WHERE
   obj.type='U'
   AND ind.index_id > 0
   AND avg_fragmentation_in_percent>5

-----------Kurzor---------------------
DECLARE @SQL VARCHAR(255)
DECLARE @DB_Index VARCHAR(255)
DECLARE @DB_Schema VARCHAR(255)
DECLARE @DB_Table VARCHAR(255)
DECLARE @OperationToMaintenance VARCHAR(255)

DECLARE index_cursor CURSOR FOR (SELECT DB_Index,DB_Schema,DB_Table,OperationToMaintenance FROM @TablesToMaintenance)

OPEN index_cursor
FETCH NEXT FROM index_cursor INTO @DB_Index, @DB_Schema, @DB_Table, @OperationToMaintenance
WHILE @@FETCH_STATUS = 0
  BEGIN
    SET @SQL= 'Alter INDEX [' + @DB_Index + '] ON [' + @DB_Schema + '].[' + @DB_Table + '] ' + @OperationToMaintenance
    EXECUTE (@SQL)
    FETCH NEXT FROM index_cursor INTO @DB_Index, @DB_Schema, @DB_Table, @OperationToMaintenance
  END
CLOSE index_cursor
DEALLOCATE index_cursor

Enjoy

Edit 11.12.2018 – upraven skript uvnitř kurzoru – sestavení dynamického SQL. Je vhodné používat hranaté závorky, protože některé automaticky vytvořené sql indexy mají různé zlobivé znaky nebo mezery a execute SQL s podobnými znaky končí failem. Do budoucna si dávám předsevzetí dávat hranaté závorky všude kam patří, je to optional a profesionálnější přístup.

5/5 - (3 votes)

Ing. Jan Zedníček - Data Engineer & Controlling

Jmenuji se Honza Zedníček a působím jako freelancer. Pracoval jsem dříve také jako BI developer, finanční controller a analytik. Vše pro společnosti z oblasti IT, bankovnictví, consultingu a výroby. Po práci si rád zahraju tenis, volejbal, šachy, zajdu do posilovny a občas neúspěšně odpálím pár balónků v golfu 🏌️

Již cca 10 let zapisuji na tento web různé návody určené zejména odborné veřejnosti, studentům a zájemcům o informace z oblastí Business intelligence, korporátních financí a reportingu.

🔥 Přihlašte se do naší Excel facebook skupiny (2.4k+ členů), kde si pomáháme Excel CZ/SK diskuse »

Leave a Reply

Your email address will not be published. Required fields are marked *