it-swarm.com.de

Warum ist meine Datenbank immer noch fragmentiert, nachdem ich alles neu erstellt und indiziert habe?

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.

41
Justin Dearing

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.

38

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 .

20
Marian

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;
12
Aaron Bertrand