Dieses Blog durchsuchen

Freitag, 17. Juli 2015

UpdateStatistic Skript

Eine weitere regelmäßige Tätigkeit ist es, die Statistiken aktuell zu halten.
Anbei ein kleines Skript, welches in der Erstversion bereits einige Steuerungsmöglichkeiten enthält. 


USE [MyDatabase]
GO

---------------------------------------------------
-- Produced By   : Stefan Perner
-- URL           : www.sqlwithpleasure.blogspot.co.at
-- Author        : Stefan Perner 
-- Date          : 2015-07-17
-- Purpose       : Database Maintenance - Statisticupdate
-- Modifications : no changes, as perfect
------------------------------------------------------------

/*#####################################################################*/
/*############ DIESE WERTE VOR DER AUSFÜHRUNG ÄNDERN ! ################*/
/*#####################################################################*/
DECLARE @Resample             int    = 0;    
     -- 0|1 Schalter - wenn 1, erfolgt der StatUpd. mit Resample,
     -- und somit wie bei der letzten Durchführung
     -- wenn 0, wird nach Satzanz. gesteuert, wieviele gesampelt werden.
DECLARE @Exec                 int    = 0;    
     -- 0|1 Schalter - wenn 1, wird das SQL auch ausgeführt, 
     --0 ist nur für Analyse
DECLARE @Print                int    = 1;    
     -- 0|1 Schalter - wenn 1, wird das SQL zusätzlich ausgegeben
/*######################################################################*/

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

DECLARE @SatzanzahlVeraendert int = 0;
DECLARE @Satzanzahl           int = 0;
DECLARE @SchemaName           nvarchar(130);
DECLARE @TableName            nvarchar(130);
DECLARE @IndexName            nvarchar(130);
DECLARE @Command              nvarchar(4000);

/*
   Für den Statistikupdate relevante Daten ermitteln
   Einschränkung auf Indizes, welche überhaupt veränderte Daten haben, 
   Microsoft interne Indizes werden ausgeschlossen
   Optional kann hier eingeschränkt werden, dass nur Indizes mit einer mind./max. Anzahl 
     von Sätzen berücksichtigt werden
*/

SELECT sSchem.name          AS SchemaName
  , sTab.name        AS TableName
  , sInd.name        AS IndexName
  , ssInd.rowcnt     AS Satzanzahl
  , ssInd.rowmodctr  AS SatzanzahlVeraendert
  INTO #IndizesFuerUpdateStatistic
  FROM sys.indexes AS sInd
 INNER JOIN sys.sysindexes AS ssInd 
    ON sInd.object_id     = ssInd.id
   AND sInd.name          = ssInd.name
 INNER JOIN sys.tables AS sTab 
    ON sTab.[object_id]   = sInd.[object_id]
 INNER JOIN sys.schemas AS sSchem 
    ON sSchem.[schema_id] = sTab.[schema_id]
 WHERE sTab.is_ms_shipped = 0 -- Only application indexes
   AND ssInd.rowcnt       > 100 -- Only indexes with at least 100 rows
   AND ssInd.rowmodctr    > 0 -- Only indexes with changed data
 
-- Cursor deklarieren und öffnen
DECLARE C_Indizes CURSOR FOR SELECT * FROM #IndizesFuerUpdateStatistic;
OPEN C_Indizes;

-- Schleife zum abarbeiten der Statistikupdates - hier wird auch gesteuert, 
-- wie die Statisticupdates durchgeführt werden.
WHILE (1=1)
BEGIN;
FETCH NEXT
FROM C_Indizes
INTO @SchemaName, @TableName, @IndexName, @Satzanzahl, @SatzanzahlVeraendert;
 BEGIN TRY
   IF @@FETCH_STATUS < 0 BREAK; -- wenn kein Satz mehr im Cursor, dann Schleife verlassen

   SET @Command = N'UPDATE STATISTICS '
                + QUOTENAME(@SchemaName) 
                   + N'.' 
                   + QUOTENAME(@TableName)
                   + N' ' 
                   + QUOTENAME(@IndexName) 
   IF @Resample = 1
   BEGIN
  SET @Command = @Command + N' WITH RESAMPLE';
      END
      ELSE IF @Resample = 0
      BEGIN
        SET @Command = @Command 
                   + N' WITH SAMPLE '
                   + CASE
                       WHEN @Satzanzahl < 100000     THEN N'100 PERCENT'
                       WHEN @Satzanzahl < 500000     THEN N'50 PERCENT'
                       WHEN @Satzanzahl < 10000000   THEN N'25 PERCENT'
                       WHEN @Satzanzahl < 30000000   THEN N'10 PERCENT'
                       WHEN @Satzanzahl < 50000000   THEN N'5 PERCENT'
                       WHEN @Satzanzahl < 100000000  THEN N'1 PERCENT'
                       ELSE N'500000 ROWS '
                     END
      END
--
      SET @Command = @Command + N' -- ' + CAST(@Satzanzahl AS VARCHAR(22)) + N' rows'
--
      IF @Print = 1
        PRINT N'Abzusetzendes Statement: ' +  @Command
--
      IF @Exec = 1
        EXEC (@Command)
--
 BEGIN TRAN
 COMMIT TRAN
 END TRY
 BEGIN CATCH
 ROLLBACK TRAN
 PRINT 'ERROR ENCOUNTERED'
 END CATCH
END; -- Ende der Schleife!

-- Cursor schließen und auch deallokieren
CLOSE C_Indizes;
DEALLOCATE C_Indizes;


DROP TABLE #IndizesFuerUpdateStatistic



Keine Kommentare:

Kommentar veröffentlichen