Announcement

Collapse
No announcement yet.

Index reorganisieren

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Index reorganisieren

    Hallo an alle,
    habe unter http://msdn.microsoft.com/de-de/library/ms188917.aspx ein gutes Beispiel gefunden um Indexe neu zu erstellen bzw. zu organisieren.
    --Hier mal das Beispiel:
    -- Ensure a USE <databasename> statement has been executed first.
    SET NOCOUNT ON;
    DECLARE @objectid int;
    DECLARE @indexid int;
    DECLARE @partitioncount bigint;
    DECLARE @schemaname nvarchar(130);
    DECLARE @objectname nvarchar(130);
    DECLARE @indexname nvarchar(130);
    DECLARE @partitionnum bigint;
    DECLARE @partitions bigint;
    DECLARE @frag float;
    DECLARE @command nvarchar(4000);
    -- Conditionally select tables and indexes from the sys.dm_db_index_physical_stats function
    -- and convert object and index IDs to names.
    SELECT
    object_id AS objectid,
    index_id AS indexid,
    partition_number AS partitionnum,
    avg_fragmentation_in_percent AS frag
    INTO #work_to_do
    FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, 'LIMITED')
    WHERE avg_fragmentation_in_percent > 10.0 AND index_id > 0;

    -- Declare the cursor for the list of partitions to be processed.
    DECLARE partitions CURSOR FOR SELECT * FROM #work_to_do;

    -- Open the cursor.
    OPEN partitions;

    -- Loop through the partitions.
    WHILE (1=1)
    BEGIN;
    FETCH NEXT
    FROM partitions
    INTO @objectid, @indexid, @partitionnum, @frag;
    IF @@FETCH_STATUS < 0 BREAK;
    SELECT @objectname = QUOTENAME(o.name), @schemaname = QUOTENAME(s.name)
    FROM sys.objects AS o
    JOIN sys.schemas as s ON s.schema_id = o.schema_id
    WHERE o.object_id = @objectid;
    SELECT @indexname = QUOTENAME(name)
    FROM sys.indexes
    WHERE object_id = @objectid AND index_id = @indexid;
    SELECT @partitioncount = count (*)
    FROM sys.partitions
    WHERE object_id = @objectid AND index_id = @indexid;

    -- 30 is an arbitrary decision point at which to switch between reorganizing and rebuilding.
    IF @frag < 30.0
    SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REORGANIZE';
    IF @frag >= 30.0
    SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REBUILD';
    IF @partitioncount > 1
    SET @command = @command + N' PARTITION=' + CAST(@partitionnum AS nvarchar(10));
    EXEC (@command);
    PRINT N'Executed: ' + @command;
    END;

    -- Close and deallocate the cursor.
    CLOSE partitions;
    DEALLOCATE partitions;

    -- Drop the temporary table.
    DROP TABLE #work_to_do;
    GO


    hat vielleicht jemand einen Ansatz, wie man dieses Skript anpassen kann, damit es alle Datenbanken auf einem Server durchläuft und die Indexe vorschlägt? So wie es hier steht, bezieht sich das auf nur 1 Datenbank. Das könnte man ja als Wartungsjob laufen lassen. Bräuchte einen Denkanstoß.

  • #2
    Originally posted by Skimausi2908 View Post
    Hallo an alle,
    habe unter http://msdn.microsoft.com/de-de/library/ms188917.aspx ein gutes Beispiel gefunden um Indexe neu zu erstellen bzw. zu organisieren.
    --Hier mal das Beispiel:
    -- Ensure a USE <databasename> statement has been executed first.
    .....
    snipp
    .....
    hat vielleicht jemand einen Ansatz, wie man dieses Skript anpassen kann, damit es alle Datenbanken auf einem Server durchläuft und die Indexe vorschlägt? So wie es hier steht, bezieht sich das auf nur 1 Datenbank. Das könnte man ja als Wartungsjob laufen lassen. Bräuchte einen Denkanstoß.
    Man kann nicht erkennen, ob es Dein eigener Kommentar ist oder aus dem Beispiel kopiert:
    -- Ensure a USE <databasename> statement has been executed first


    Das ist doch genau die Dimension, nach der du gefragt hast.


    Hab mir den Scriptinhalt nicht genauer angesehen. Aber ich würde das wohl per script aufrufen und "use database <parameter>" von extern mitgeben. Da hat man noch etwas Steuermöglichkeiten. Nicht alle DB müssen immer ständig optimiert werden.
    Wenn der gezeigt Code oben sauber zu Ende kommt kann man es inkl "use database" evtl auch in eine Schleife packen.

    Bin kein MSSQL Spezialist, nur meine 5 cent
    Gruß, defo

    Comment


    • #3
      Hallo,
      danke für Deine Antwort. Das Beispiel ist von Microsoft kopiert und ich fand den Skript ganz gut und wollte einen Wartungsjob bauen. Ich bleibe aber daran hängen, dass es mir nicht gelingt, alle auf dem Server befindlichen DB anzusprechen.

      Comment


      • #4
        Originally posted by Skimausi2908 View Post
        Hallo,
        danke für Deine Antwort. Das Beispiel ist von Microsoft kopiert und ich fand den Skript ganz gut und wollte einen Wartungsjob bauen. Ich bleibe aber daran hängen, dass es mir nicht gelingt, alle auf dem Server befindlichen DB anzusprechen.
        Also vielleicht habe ich mich unklar ausgedrückt.
        Nimm das Script so wie es ist, starte es per Script und gib den DB Namen als Parameter mit.
        Woher bekommst Du den?
        2. Möglichkeiten:
        Du fragst die Datenbanknamen immer ab
        oder
        Du stellst eine Parameter Liste (Textdatei) für das Script zur Verfügung

        Die 2. Lösung ist statischer, aber u.U. "sparsamer" mit den Resourcen
        die 1. Lösung ist immer vollständig, benötigt immer max Resourcen

        p.s.: hier ein paar Hinweise zur Abfrage der DB:
        http://stackoverflow.com/questions/1...rom-sql-server
        Zuletzt editiert von defo; 01.07.2014, 07:44.
        Gruß, defo

        Comment

        Working...
        X