it-swarm.com.de

Wie kann ich feststellen, WARUM eine Einfügung in eine bestimmte Tabelle langsam ist?

Ich weiß, dass ein INSERT in einer SQL-Tabelle aus einer Reihe von Gründen langsam sein kann:

  • Vorhandensein von INSERT TRIGGERs auf dem Tisch
  • Viele erzwungene Einschränkungen, die überprüft werden müssen (normalerweise Fremdschlüssel)
  • Seitenteilung im Clustered-Index, wenn eine Zeile in die Mitte der Tabelle eingefügt wird
  • Aktualisieren aller zugehörigen nicht gruppierten Indizes
  • Blockieren von anderen Aktivitäten auf dem Tisch
  • Schlecht IO Antwortzeit schreiben
  • ... was ich verpasst habe?

Wie kann ich feststellen, wer in meinem speziellen Fall verantwortlich ist? Wie kann ich die Auswirkung von Seitenteilen gegenüber nicht geclusterten Indexaktualisierungen im Vergleich zu allem anderen messen?

Ich habe einen gespeicherten Prozess, der ungefähr 10.000 Zeilen gleichzeitig einfügt (aus einer temporären Tabelle), was ungefähr 90 Sekunden pro 10.000 Zeilen dauert. Das ist inakzeptabel langsam, da andere Spids eine Zeitüberschreitung verursachen.

Ich habe mir den Ausführungsplan angesehen und sehe die Aufgabe INSERT CLUSTERED INDEX und alle INDEX SEEKS aus den FK-Lookups, aber es sagt mir immer noch nicht genau, warum es so lange dauert. Keine Trigger, aber die Tabelle enthält eine Handvoll FKeys (die anscheinend richtig indiziert sind).

Dies ist eine SQL 2000-Datenbank.

30
BradC

Einige Dinge, die Sie sich ansehen können ...

Reduzieren Sie die Stapelgröße von 10000 auf etwas Kleineres wie 2000 oder 1000 (Sie haben nicht angegeben, wie groß Ihre Zeilengröße ist).

Aktivieren Sie IO Stats, um zu sehen, wie viel IO die FK-Lookups benötigen).

Was ist das Warten, wenn das Einfügen erfolgt (master.dbo.sysprocesses)?

Fangen wir hier an und sehen, wohin wir gehen.

10
mrdenny

Brad,

Sie sollten die Wartestatistiken für Ihre Abfrage überprüfen. Mit SQL 2000 können Sie die DBCC SQLPERF-Syntax ("wait stats") verwenden, um diese Details abzurufen.

7
SQLRockstar

Ich kann sagen, wonach ich suche, wenn ich die Leistung einer Abfrage analysiere. Vielleicht hilft es.

  • analysieren Sie den Ausführungsplan für Abfragen und suchen Sie nach Index-Scans, Tabellenscans, Verwendung von convert_implicit-Funktionen für SQL-Datentypen und Parallelität.
  • führen Sie die Abfrage mit SET STATISTICS IO ON und SET STATISTICS TIME ON) aus, um die Ausführungszeit anzuzeigen und io für jede Einfügung zu lesen/schreiben.
  • überprüfen Sie die Wartezeit von sysprocesses auf Ihre Sitzung.
  • führen Sie den Profiler aus und wählen Sie die Standardvorlage aus. Wählen Sie Folgendes aus: Leistungsstatistik (wenn wiederholt, wird Ihr Plan viele Male kompiliert - nicht gut), RPC: abgeschlossen, SQL: Batch abgeschlossen und SQL: Batchstart. Fügen Sie ihnen die Spalte Zeilenanzahl hinzu, um genau die Anzahl der Zeilen im Stapel anzuzeigen. Filtern Sie die Ergebnisse, um nur Ihre Abfrage anzuzeigen.
  • endlich sammeln Page Life Expectancy Zähler von Windows Perfmon und wenn es unter 300 (5 min) ist, dann hat die SQL wenig Speicher. Sammeln Sie auch die Festplattenzähler: Länge der Festplattenwarteschlange, Festplattenzeit (Laufwerk Ihrer Datendateien), Festplattenzeit (Laufwerk Ihrer Protokolldateien), um festzustellen, ob Druck auf die Festplatten ausgeübt wird.
6
yrushka

Versuchen Sie es mit:

SET STATISTICS IO ON

und

SET STATISTICS PROFILE ON

STATISTICS IO

Kann hilfreich sein, um Ihnen mitzuteilen, welche Tabellen die meisten Tabellenscans, logischen und physischen Lesevorgänge ausführen (ich verwende diese drei, um mich darauf zu konzentrieren, welcher Teil des Abfrageplans am meisten optimiert werden muss).

STATISTIKPROFIL

Wenn der Abfrageplan in erster Linie in Tabellenform zurückgegeben wird, können Sie in den Spalten IO und CPU) nachsehen, was in der Abfrage den größten Betrag kostet (ist es der Tabellenscan in Ihrer temporären Tabelle?) im Vergleich zu der Art, die zum Einfügen in Ihren Clustered Key usw. verwendet wird.

5