Benutzer mit den meisten Antworten
Index reorganisieren

Frage
-
Hallo,
ich habe ein kleines Problem mit dem Punkt Index reorganisieren.
Wenn ich mir die Fragmentierung der Indices anschaue, dann mekre ich, dass auf meiner DB einige bis zu 99% fragmentiert sind.
Ich sehe aber nicht, in welcher Tabelle, bzw. welcher Index es ist. Ich sehe hier nur eine Database_ID, eine Object_ID und eine Index_ID.
Kann mir jemand sagen, wie ich von diesen IDs auf den namen komme?
Vielen Dank.
Gruß
TimoB.
Antworten
-
Hallo Timo,
ich weiss ja nicht, woher Du die Daten erhälst, aber im Normalfall joine die sys.objects, sys.indexes usw. hinzu, z. B.:
SELECT o.name AS TableName, i.name AS IndexName, ips.avg_fragmentation_in_percent FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'DETAILED') AS ips INNER JOIN sys.objects AS o ON ips.object_id = o.object_id INNER JOIN sys.indexes AS i ON ips.object_id = i.object_id AND ips.index_id = i.index_id WHERE ips.avg_fragmentation_in_percent > 10 order by ips.object_id, ips.index_id, ips.partition_number
zudem gibt es Funktionen wie DB_NAME , OBJECT_NAME uam.
In der Dokumentation zu dm_db_index_physical_stats (nur auf den englischen Seiten zu sehen)
findest Du in den Beispielen ein Skript zum Reorganisieren respektive Neuaufbau.
Weitere Erläuterungen findest Du unter Neuorganisieren und Neuerstellen von Indizes
Gruß Elmar- Als Antwort markiert TimoB_ Freitag, 18. Dezember 2009 10:14
-
Ich habe mit deiner Beschreibung und ein paar anderen Quellen ein neues Statement zusammengebaut.
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); -- Tabellen und Indizes aus sys.dm_db_index_physical_stats auslesen -- Objekt und Index IDs in Namen konvertieren 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; -- Cursor Deklaration DECLARE partitions CURSOR FOR SELECT * FROM #work_to_do; OPEN partitions; -- Schleife durch die einzelnen Partitionen 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 ist laut MS der Punkt zwischen reorganize und rebuild 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; -- Cursor schliessen und deallocate CLOSE partitions; DEALLOCATE partitions; -- Temporäre Tabelle löschen DROP TABLE #work_to_do; GO
Gruß- Als Antwort markiert TimoB_ Freitag, 5. August 2011 14:26
Alle Antworten
-
Hallo Timo,
ich weiss ja nicht, woher Du die Daten erhälst, aber im Normalfall joine die sys.objects, sys.indexes usw. hinzu, z. B.:
SELECT o.name AS TableName, i.name AS IndexName, ips.avg_fragmentation_in_percent FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'DETAILED') AS ips INNER JOIN sys.objects AS o ON ips.object_id = o.object_id INNER JOIN sys.indexes AS i ON ips.object_id = i.object_id AND ips.index_id = i.index_id WHERE ips.avg_fragmentation_in_percent > 10 order by ips.object_id, ips.index_id, ips.partition_number
zudem gibt es Funktionen wie DB_NAME , OBJECT_NAME uam.
In der Dokumentation zu dm_db_index_physical_stats (nur auf den englischen Seiten zu sehen)
findest Du in den Beispielen ein Skript zum Reorganisieren respektive Neuaufbau.
Weitere Erläuterungen findest Du unter Neuorganisieren und Neuerstellen von Indizes
Gruß Elmar- Als Antwort markiert TimoB_ Freitag, 18. Dezember 2009 10:14
-
Hi zusammen
Heute bin auf einen anderen Punkt zu diesem Thema gestossen:
die Indizes in einigen meiner DBs sind extrem groß und fragmentiert.
Was wäre hier nun besser? REORGANIZE oder REBUILT
Und wie kann ich alle Indizes einer DB reorganisieren bzw. neu aufbauen?
Danke und Gruß
-
Wenn ein neues Thema dann ein neuer Eintrag.
Die Anwort auf all deine Fragen findest du hier:
http://realworlddba.wordpress.com/2008/01/27/indexes-to-rebuild-or-reorganize/
Ich bin mir nicht sicher, ob das alle Fragen beantwortet, bzw. für alle Environments gleichermassen gültig ist.Fwiw, ich habe meine Erfahrungen mal hier zusammengefasst: http://www.insidesql.org/blogs/frankkalis/2011/02/02/index-maintenance-oder-dm_db_index_physical_stats-ist-langsam
-- Frank Kalis Microsoft SQL Server MVP Webmaster: http://www.insidesql.org -
Ich habe mit deiner Beschreibung und ein paar anderen Quellen ein neues Statement zusammengebaut.
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); -- Tabellen und Indizes aus sys.dm_db_index_physical_stats auslesen -- Objekt und Index IDs in Namen konvertieren 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; -- Cursor Deklaration DECLARE partitions CURSOR FOR SELECT * FROM #work_to_do; OPEN partitions; -- Schleife durch die einzelnen Partitionen 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 ist laut MS der Punkt zwischen reorganize und rebuild 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; -- Cursor schliessen und deallocate CLOSE partitions; DEALLOCATE partitions; -- Temporäre Tabelle löschen DROP TABLE #work_to_do; GO
Gruß- Als Antwort markiert TimoB_ Freitag, 5. August 2011 14:26