Fragmentierung der physischen SQL-Datenbankdatei

19

Ich weiß, dass es wirklich drei Arten von Fragmentierung gibt, um die ich mich als DBA kümmern muss:

  1. Index Fragmentation in den SQL - Datendateien, einschließlich Cluster - Index (Tabelle) Fragmentierung. Identifizieren Sie dies mit DBCC SHOWCONTIG (in SQL 2000) oder sys.dm_db_index_ physical_ stats (in 2005+).

  2. VLF-Fragmentierung in SQL-Protokolldateien. Führen Sie DBCC LOGINFO aus, um festzustellen, wie viele VLFs sich in jeder Ihrer SQL-Protokolldateien befinden.

  3. Physische Dateifragmentierung der Datenbankdateien auf der Festplatte. Diagnostizieren Sie dies mithilfe des Dienstprogramms "Defragmentierung" in Windows. (inspiriert von diesem exzellenten Blog-Beitrag )

Der Indexfragmentierung wird viel Aufmerksamkeit geschenkt (siehe diese ausgezeichnete Serverfault-Antwort von Paul Randall), daher ist dies nicht der Schwerpunkt meiner Frage.

Ich weiß, dass ich eine physische Fragmentierung (und VLF-Fragmentierung) verhindern kann , wenn die Datenbank ursprünglich erstellt wird, indem ich eine angemessene erwartete Datendatei und Protokollgröße plane, da diese Fragmentierung am häufigsten durch häufiges Anwachsen und Verkleinern auftritt, aber ich habe einige Fragen zum Beheben Physische Fragmentierung, sobald sie identifiziert wurde:

  • Ist die physische Fragmentierung in einem Enterprise-SAN überhaupt relevant? Kann / sollte ich Windows Defragmenter auf einem SAN-Laufwerk verwenden oder sollte das SAN-Team interne Defragmentierungsdienstprogramme verwenden? Ist die Fragmentierungsanalyse, die ich mit dem Windows-Tool erhalte, auch auf einem SAN-Laufwerk genau ?

  • Wie groß ist die physische Fragmentierung der SQL-Leistung? (Nehmen wir ein internes Laufwerk-Array an, bis das Ergebnis der vorherigen Frage vorliegt.) Handelt es sich um ein größeres Geschäft als um eine interne Indexfragmentierung? Oder ist es wirklich dasselbe Problem (das Laufwerk muss zufällige Lesevorgänge anstelle von sequentiellen Lesevorgängen durchführen)?

  • Ist das Defragmentieren (oder Neuerstellen) von Indizes eine Zeitverschwendung, wenn das Laufwerk physisch fragmentiert ist? Muss ich den einen reparieren, bevor ich den anderen anspreche?

  • Was ist der beste Weg, um physische Dateifragmentierung auf einer Produktions-SQL-Box zu beheben? Ich weiß, dass ich SQL-Dienste deaktivieren und Windows Defrag ausführen kann, aber ich habe auch von einer Technik gehört, bei der Sie eine vollständige Sicherung durchführen, die Datenbank löschen und dann von der Sicherung auf ein leeres Laufwerk zurückschreiben. Wird diese letztere Technik empfohlen? Baut das Wiederherstellen von einer solchen Sicherung auch Indizes von Grund auf auf und beseitigt die interne Indexfragmentierung? Oder wird die Seitenreihenfolge einfach auf den gleichen Wert zurückgesetzt, als die Sicherung erstellt wurde? (Wir verwenden Quest Lightspeed-Backups mit Komprimierung, falls dies von Bedeutung ist.)

UPDATE : Gute Antworten zur Defragmentierung von SAN-Laufwerken (NO) und zur Frage, ob sich die Indexdefragmentierung auf physisch fragmentierten Laufwerken noch lohnt (YES).

Möchte noch jemand die besten Methoden für die eigentliche Defragmentierung abwägen? Oder eine Schätzung der zu erwartenden Zeitdauer für die Defragmentierung eines großen fragmentierten Laufwerks, z. B. 500 GB oder so? Relevant, offensichtlich, weil das die Zeit ist, in der mein SQL Server ausfällt!

Auch wenn jemand irgendwelche anekdotischen Informationen über SQL-Leistungsverbesserungen hat, die Sie durch das Reparieren der physischen Fragmentierung vorgenommen haben, wäre das großartig. In Mikes Blogpost geht es darum, das Problem aufzudecken, aber es ist nicht spezifisch, welche Art von Verbesserung es bewirkt hat.

BradC
quelle

Antworten:

9

Ich denke, dieser Artikel bietet einen hervorragenden Überblick über die Defragmentierung von SAN-Laufwerken

http://www.las-solanas.com/storage_virtualization/san_volume_defragmentation.php

Grundsätzlich wird die Defragmentierung im SAN-Speicher nicht empfohlen, da es schwierig ist, den physischen Speicherort von Blöcken auf der Festplatte zu korrelieren, wenn der Speicherort beim Präsentieren der LUN vom SAN virtualisiert wurde.

Wenn Sie RAW-Gerätezuordnungen verwendet haben oder direkten Zugriff auf ein RAID-Set haben, das die LUN ist, mit der Sie arbeiten, könnte sich eine Degfragmentierung positiv auswirken. 5 Satz, Nr.

Kevin Kuphal
quelle
Ausgezeichneter Artikel. Genau das Richtige für SAN-Laufwerke.
BradC
7

Mehrere Teile zu dieser Frage und Antwort:

Die physische Dateifragmentierung ist für Enterprise SAN-Speicher nicht wirklich relevant, wie Kevin bereits betont hat - daher gibt es dort nichts hinzuzufügen. Es kommt wirklich auf das E / A-Subsystem an und wie wahrscheinlich es ist, dass Sie die Laufwerke dazu bringen können, bei der Durchführung eines Scans von mehr zufälligen E / A zu mehr sequenziellen E / A zu wechseln, wenn Sie einen Scan durchführen. Für DAS ist es wahrscheinlicher, dass Sie es tun, für ein komplexes Slice-n-Dice-SAN wahrscheinlich nicht.

Defragmentierung auf Dateisystemebene - nur mit heruntergefahrenem SQL. Ich habe hier selbst noch nie Probleme gehabt (da ich noch nie eine offene Onlinedefragmentierung von SQL-Datenbankdateien durchgeführt habe), aber ich habe von Kunden und Kunden zahlreiche Einzelfälle in Bezug auf seltsame Korruptionsprobleme gehört. Allgemeine Weisheit ist, es nicht mit SQL Online zu tun.

Die Indexfragmentierung ist vollständig orthogonal zur Dateifragmentierung. SQL Server hat keine Ahnung von Dateifragmentierung - zu viele Virtualisierungsebenen dazwischen, als dass es die Hoffnung hätte, die tatsächlichen Geometrien des E / A-Subsystems zu ermitteln. Bei der Indexfragmentierung weiß SQL jedoch alles. Ohne mich zu sehr von der Antwort zu wiederholen, auf die Sie bereits verwiesen haben, verhindert die Indexfragmentierung, dass SQL einen effizienten Readahead für den Bereichsscan durchführt, unabhängig davon, wie fragmentiert (oder nicht) die Dateien auf Dateisystemebene sind. Daher sollten Sie unbedingt die Indexfragmentierung verringern, wenn die Abfrageleistung abnimmt.

Sie müssen nicht haben zu tun , diese in einer bestimmten Reihenfolge, obwohl , wenn Sie Dateisystemfragmentierung kümmern und dann alle Ihre Indizes neu erstellen und Dateisystemfragmentierung verursachen , indem sie mehrere Dateien auf einem defragged Volumen wächst, sind Sie wahrscheinlich gehen abgehakt werden. Wird es dennoch Probleme mit der Perfektion geben? Wie oben diskutiert, kommt es darauf an :-D

Hoffe das hilft!

Paul Randal
quelle
Ah, ändert also die interne Indexfragmentierung tatsächlich das Verhalten des Optimierers, um vollständige Scans zu bevorzugen, anstatt nach einem geeigneten Indexbereich zu suchen?
BradC
Nein. Das Optimierungsprogramm hat keine Kenntnis davon, wie die Daten auf der Festplatte gespeichert werden, abgesehen von der Tatsache, dass Indizes vorhanden sind, ihrer Größe und der Statistik der Spaltenwertverteilung. Die Storage Engine steuert den Readahead und ändert die einzelnen E / A-Größen basierend auf der logischen Fragmentierung des Scanvorgangs.
Paul Randal
3

Was ist der beste Weg, um physische Dateifragmentierung auf einer Produktions-SQL-Box zu beheben?

Ich führe SYSINTERNALS 'contig auf meinen Datenbankdateien aus.

Siehe http://technet.microsoft.com/en-us/sysinternals/bb897428.aspx

Vincent Buck
quelle
Sieht interessant aus. Ich nehme an, da es die Windows-Defragmentierungs-APIs verwendet, müssten die SQL-Dienste ausgeschaltet sein. Oder würde dies ausgeführt, während der Server / die Datenbank online ist?
BradC
Ich habe es erfolgreich in Online-MSSQL Server-Datenbanken verwendet. Aber das waren wohl wenig Verkehr und kleine Datenbanken (weniger als 10 GB)
Vincent Buck
Dies ist ein großartiges Werkzeug! Ich denke, dass die Anwendungen für Datenbanken, wie von anderen erwähnt, ziemlich begrenzt sind, aber ich liebe sie für andere Arten von Laufwerken. Der Analysemodus -a ist während des Betriebs sicher. Ich würde mich nicht sicher fühlen, wenn ich es auf einem Laufwerk eines Live-SQL-Servers laufen lasse.
Kendra
2

Ich würde empfehlen, die Größe der Datenbank entsprechend anzupassen, den SQL-Server herunterzufahren, die Datenbankdatei auf ein anderes Festplatten-Array zu kopieren und sie dann zum Defragmentieren zurück zu kopieren. Nach meiner Erfahrung viel schneller als mit Windows defragmentieren.


quelle
1

Ich habe versucht, die physischen Laufwerke in einer SCSI-Lösung einmal zu defragmentieren, habe aber kaum oder gar keinen Leistungsschub erhalten. Die Lektion, die ich gelernt habe, ist, dass, wenn Sie aufgrund des Festplattensystems auf eine langsame Leistung stoßen, dies nichts mit der Fragmentierung zu tun hat, sofern es sich um eine Datendatei handelt, da sie wahlfreien Zugriff verwendet.

Wenn Ihre Indizes defragmentiert und die Statistiken aktualisiert werden (sehr wichtig) und Sie die E / A weiterhin als Engpass betrachten, leiden Sie unter anderen Problemen als der physischen Fragmentierung. Haben Sie mehr als 80% des Laufwerks genutzt? Hast du genug Laufwerke? Sind Ihre Abfragen ausreichend optimiert? Machst du viel Table-Scan oder noch schlimmer viel Index-Suche gefolgt von Clustered-Index-Lookup? Schauen Sie sich die Abfragepläne an und verwenden Sie "Statistiken einstellen", um herauszufinden, was mit Ihrer Abfrage wirklich los ist. (Achten Sie auf eine hohe Anzahl logischer oder physischer Lesevorgänge.)

Bitte lassen Sie mich wissen, wenn ich völlig falsch liege.

/ Håkan Winther

Hakan Winther
quelle
Nein, du liegst nicht falsch. Der Versuch, einige serverweite Verbesserungen vorzunehmen (falls möglich), ist jedoch etwas attraktiver, als sich mit den über 150.000 verschiedenen SQL-Anweisungen zu beschäftigen, die während der wöchentlichen Analysejobs ausgeführt werden (keine Übertreibung.
Eigentlich
In solchen Situationen würde ich Veritas I3 empfehlen, Ihre Umgebung zu analysieren, um festzustellen, unter welchem ​​Engpass Sie leiden und was den Engpass verursacht. Veritas I3 protokolliert alle Kontoauszüge und wie oft und zu welchen Kosten sie abgerufen werden. Es ist eine ausgezeichnete Software.
Hakan Winther
1

Möglicherweise sind die Indizes nicht ausreichend für Ihre Anwendung optimiert, und Sie verfügen nicht über Veritas I3, um Ihre Datenbank zu optimieren. Dann könnten Sie eine Anweisung wie die folgende verwenden, um fehlende Indizes zu finden:

       SELECT
      mid.statement,
      mid.equality_columns,
      mid.inequality_columns,
      mid.included_columns,
      migs.user_seeks,
      migs.user_scans,
      migs.last_user_seek,
      migs.avg_user_impact,
      user_scans,
      avg_total_user_cost,
      avg_total_user_cost * avg_user_impact * (user_seeks + user_scans) AS [weight]--, migs.*--, mid.*
   FROM
      sys.dm_db_missing_index_group_stats AS migs
      INNER JOIN sys.dm_db_missing_index_groups AS mig
         ON (migs.group_handle = mig.index_group_handle)
      INNER JOIN sys.dm_db_missing_index_details AS mid
         ON (mig.index_handle = mid.index_handle)
   ORDER BY
      avg_total_user_cost * avg_user_impact * (user_seeks + user_scans) DESC ;

Oder eine Anweisung wie diese, um Indizes zu finden, die nicht in select-Anweisungen verwendet werden und die Leistung beim Aktualisieren / Einfügen verringern:

    CREATE PROCEDURE [ADMIN].[spIndexCostBenefit]
    @dbname [nvarchar](75)
WITH EXECUTE AS CALLER
AS
--set @dbname='Chess'
declare @dbid nvarchar(5)
declare @sql nvarchar(2000)
select @dbid = convert(nvarchar(5),db_id(@dbname))

set @sql=N'select ''object'' = t.name,i.name
        ,''user reads'' = iu.user_seeks + iu.user_scans + iu.user_lookups
        ,''system reads'' = iu.system_seeks + iu.system_scans + iu.system_lookups
        ,''user writes'' = iu.user_updates
        ,''system writes'' = iu.system_updates
from '+ @dbname + '.sys.dm_db_index_usage_stats iu
,' + @dbname + '.sys.indexes i
,' + @dbname + '.sys.tables t
where 
    iu.database_id = ' + @dbid + '
and iu.index_id=i.index_id
and iu.object_id=i.object_id
and iu.object_id=t.object_id
AND (iu.user_seeks + iu.user_scans + iu.user_lookups)<iu.user_updates
order by ''user reads'' desc'

exec sp_executesql @sql

set @sql=N'SELECT
   ''object'' = t.name,
   o.index_id,
   ''usage_reads'' = user_seeks + user_scans + user_lookups,
   ''operational_reads'' = range_scan_count + singleton_lookup_count,
   range_scan_count,
   singleton_lookup_count,
   ''usage writes'' = user_updates,
   ''operational_leaf_writes'' = leaf_insert_count + leaf_update_count + leaf_delete_count,
   leaf_insert_count,
   leaf_update_count,
   leaf_delete_count,
   ''operational_leaf_page_splits'' = leaf_allocation_count,
   ''operational_nonleaf_writes'' = nonleaf_insert_count + nonleaf_update_count + nonleaf_delete_count,
   ''operational_nonleaf_page_splits'' = nonleaf_allocation_count
FROM
   ' + @dbname + '.sys.dm_db_index_operational_stats(' + @dbid + ', NULL, NULL, NULL) o,
   ' + @dbname + '.sys.dm_db_index_usage_stats u,
    ' + @dbname + '.sys.tables t
WHERE
   u.object_id = o.object_id
   AND u.index_id = o.index_id
    and u.object_id=t.object_id
ORDER BY
   operational_reads DESC,
   operational_leaf_writes,
   operational_nonleaf_writes'

exec sp_executesql @sql

GO

Ich habe einige andere SQL-Anweisungen, die ich bei der Analyse von Leistungsproblemen in der Produktionsumgebung verwende, aber diese beiden sind meiner Meinung nach ein guter Anfang.

(Ich weiß, dieser Beitrag ist ein wenig thematisch, aber ich dachte, Sie könnten interessiert sein, da es mit der Indizierungsstrategie zu tun hat.)

/ Håkan Winther

Hakan Winther
quelle
Ausgezeichnete Skripte, ich habe einige sehr ähnlich. Leider haben wir immer noch 40% SQL 2000 (einschließlich des fraglichen Servers), das keine Entsprechung zu diesen "fehlenden Index" -DMVs hat.
BradC
Ich verstehe, dann empfehle ich Ihnen, sich Veritas I3 anzusehen. Es ist ein ausgezeichnetes Produkt, mit dem Sie Ihre Datenbanken optimieren können, aber es ist keine billige Software.
Hakan Winther