Ich habe eine Datenbank, in der ich versucht habe, alle Tabellen gleichzeitig zu defragmentieren, indem ich dieses T-SQL ausgeführt habe:
SELECT
'ALTER INDEX all ON ' + name + ' REORGANIZE;' + CHAR(10) +
'ALTER INDEX all ON ' + name + ' REBUILD;'
FROM sys.tables
Kopieren Sie dann die Ausgabe, fügen Sie sie in ein neues Abfragefenster ein und führen Sie das aus. Ich habe keine Fehler erhalten, aber ich habe immer noch Fragmentierung. Ich habe versucht, beide Befehle auch separat auszuführen und bin immer noch fragmentiert. Hinweis : Mir wurde bewusst gemacht, dass REORGANIZE
von Aaron nicht benötigt wird, und ich bin mir bewusst, dass ich dynamisches SQL verwenden könnte, um dies zu automatisieren.
Ich habe dies ausgeführt, um festzustellen, dass ich immer noch fragmentiert bin:
SELECT * FROM
sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, NULL)
WHERE avg_fragmentation_in_percent > 0
Und ich habe:
database_id object_id index_id partition_number index_type_desc alloc_unit_type_desc index_depth index_level avg_fragmentation_in_percent fragment_count avg_fragment_size_in_pages page_count avg_page_space_used_in_percent record_count ghost_record_count version_ghost_record_count min_record_size_in_bytes max_record_size_in_bytes avg_record_size_in_bytes forwarded_record_count compressed_page_count
85 171147655 1 1 CLUSTERED INDEX IN_ROW_DATA 2 0 36.3636363636364 5 2.2 11 NULL NULL NULL NULL NULL NULL NULL NULL NULL
85 421576540 1 1 CLUSTERED INDEX IN_ROW_DATA 2 0 75 7 1.14285714285714 8 NULL NULL NULL NULL NULL NULL NULL NULL NULL
85 965578478 1 1 CLUSTERED INDEX IN_ROW_DATA 2 0 14.7058823529412 6 5.66666666666667 34 NULL NULL NULL NULL NULL NULL NULL NULL NULL
85 1061578820 1 1 CLUSTERED INDEX IN_ROW_DATA 2 0 40 4 1.25 5 NULL NULL NULL NULL NULL NULL NULL NULL NULL
85 1109578991 1 1 CLUSTERED INDEX IN_ROW_DATA 2 0 30.7692307692308 5 2.6 13 NULL NULL NULL NULL NULL NULL NULL NULL NULL
85 1205579333 2 1 NONCLUSTERED INDEX IN_ROW_DATA 2 0 50 5 1.6 8 NULL NULL NULL NULL NULL NULL NULL NULL NULL
85 1493580359 1 1 CLUSTERED INDEX IN_ROW_DATA 2 0 50 6 1.66666666666667 10 NULL NULL NULL NULL NULL NULL NULL NULL NULL
Ich weiß, dass mir etwas wirklich Grundlegendes fehlt, aber ich weiß nicht was.
Die Tische sind winzig. Die Seitenzahlen in Ihren Tabellen sind:
11, 8, 6, 5, 13, 8, 10
Sie belegen insgesamt 480 KB. Es gibt buchstäblich nichts zu defragmentieren.
Bearbeiten: Dies erfordert etwas mehr Erklärung.
Einer neuen Tabelle oder einem neuen Index werden normalerweise die ersten 8 Seiten in gemischtem und nicht in einheitlichem Umfang zugewiesen. Es ist also möglich, dass jede der ersten 8 Seiten aus verschiedenen gemischten Bereichen zugeordnet wird. Eine Tabelle oder ein Index, der 8 Seiten verbraucht, kann daher 8 Fragmente enthalten, jeweils 1 auf 8 verschiedenen gemischten Ausmaßen.
Die am häufigsten verwendeten Defragmentierungsskripte (einige der unten verlinkten Beispiele) schließen aus diesem Grund kleine Tabellen aus. IIRC, <500 Seiten befinden sich in einer oder beiden. Bei diesen Größen hat die Defragmentierung nur einen sehr geringen Nutzen, und die Fragmentierungszahlen werden möglicherweise durch die Zuordnungen gemischter Ausmaße verzerrt.
Zitat aus " Best Practices für die Microsoft SQL Server 2000-Indexdefragmentierung ":
"Die Fragmentierung wirkt sich auf die Festplatten-E/A aus. Konzentrieren Sie sich daher auf die größeren Indizes, da deren Seiten weniger wahrscheinlich von SQL Server zwischengespeichert werden. Verwenden Sie die von DBCC SHOWCONTIG gemeldete Seitenzahl, um eine Vorstellung von der Größe der Indizes zu erhalten (jede Seite ist 8 KB groß). Im Allgemeinen sollten Sie sich nicht mit Fragmentierungsstufen von Indizes mit weniger als 1.000 Seiten befassen. In den Tests erzielten Indizes mit mehr als 10.000 Seiten Leistungssteigerungen mit den größten Gewinne bei Indizes mit deutlich mehr Seiten (mehr als 50.000 Seiten) . "
Diese Art beantwortet Ihre Frage und unterstützt die Antworten von Mark und Aaron.
Gute Informationen zur Indexfragmentierung finden Sie in den folgenden Artikeln von Brent Ozar:
Ein Ozean mit großartigen Informationen über Indizes im Allgemeinen (auch über Fragmentierungsprobleme) finden Sie auf Kimberly Tripps Blog .
Dies ist nicht dazu gedacht, Ihre Frage zu beantworten, aber es wird niemals in einen Kommentar passen. Sie können dieses Skript dynamisch erstellen, ohne die Ausgabe kopieren und in ein anderes Fenster einfügen zu müssen. Unter Berücksichtigung, dass es absolut keinen Grund gibt, REORGANIZE
und dann REBUILD
:
DECLARE @sql NVARCHAR(MAX) = N'';
SELECT @sql += N'ALTER INDEX all ON ' + name + ' REBUILD;
' FROM sys.tables;
PRINT @sql; -- to see the first 8,000 characters and make sure it checks out
-- EXEC sp_executesql @sql;