Woran erkenne ich, warum eine Einfügung in einer bestimmten Tabelle langsam ist?

29

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)
  • Die Seite wird im Clustered-Index aufgeteilt, 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
  • Schlechte Antwortzeit für E / A-Schreibvorgänge
  • ... was ich verpasst habe?

Wie kann ich feststellen, welche in meinem speziellen Fall verantwortlich ist? Wie kann ich die Auswirkung von Seitenteilen im Vergleich zu nicht gruppierten Indexaktualisierungen im Vergleich zu allem anderen messen?

Ich habe eine gespeicherte Prozedur, die ungefähr 10.000 Zeilen gleichzeitig einfügt (aus einer temporären Tabelle), was ungefähr 90 Sekunden pro 10k Zeilen dauert. Das ist inakzeptabel langsam, da andere Spids ausfallen.

Ich habe mir den Ausführungsplan angesehen und sehe die INSERT CLUSTERED INDEX-Task 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 korrekt indiziert zu sein scheinen).

Dies ist eine SQL 2000-Datenbank.

BradC
quelle
Haben Sie die automatische Erweiterung für Ihre Datendateien aktiviert? Dies kann zu Leistungsproblemen bei der Standardkonfiguration führen.
Larry Coleman
Sprechen wir über die Verwendung eines Profilers? msdn.microsoft.com/en-us/library/ms187929.aspx
Inkognito
@ Larry: Datendateien haben einen erheblichen freien Speicherplatz, daher glaube ich nicht, dass das Wachstum von Datendateien ein Problem darstellt. Gut, um die "Dinge zu überprüfen" -Liste hinzuzufügen.
BradC
@ user210: Das Profilieren der Anweisungsvervollständigung zeigt mir nur, dass es 90 Sekunden gedauert hat. Es sagt mir nicht, WARUM. Es sei denn, es gibt andere Ereignisse, die Ihrer Meinung nach aussagekräftiger wären.
BradC

Antworten:

10

Einige Dinge, die Sie anschauen können ...

Reduzieren Sie die Stapelgröße von 10000 auf einen kleineren Wert, z. B. 2000 oder 1000 (Sie haben nicht angegeben, wie groß Ihre Zeilengröße ist).

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

Was ist die Wartezeit beim Einfügen (master.dbo.sysprocesses)?

Beginnen wir hier und sehen, wohin wir gehen.

mrdenny
quelle
2
Das Verringern der Stapelgröße hilft (1000 Datensätze dauern ~ 25 Sekunden). Das dürfte unsere derzeitige "Problemumgehung" sein. Ich werde sehen, ob ich E / A-Statistiken und Wartezeiten ermitteln kann (der Job wird vom Client bei Bedarf ausgeführt, wenn er eine zu verarbeitende Datei hat, sodass ich nicht immer vorhersagen kann, wann der Job tatsächlich ausgeführt wird).
BradC
7

Brad,

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

SQLRockstar
quelle
6

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

  • Analysieren des Abfrageausführungsplans und Überprüfen auf Index-Scans, Tabellenscans, Verwendung von convert_implicit-Funktionen für SQL-Datentypen, Parallelität.
  • Führen Sie die Abfrage mit SET STATISTICS IO ON und SET STATISTICS TIME ON aus, um die Ausführungszeit und den Lese- / Schreibzugriff für jede Einfügung anzuzeigen.
  • Überprüfen Sie die Wartezeit von sysprocesses auf Ihre Sitzungs-Spid.
  • Führen Sie den Profiler aus und wählen Sie eine 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 Spaltenzeilenzahlen hinzu , um genau die Anzahl der Zeilen im Stapel anzuzeigen . Filtern Sie die Ergebnisse, um nur Ihre Suchanfrage anzuzeigen.
  • Sammeln Sie endlich den Page Life Expectancy Counter von Windows Perfmon und wenn er unter 300 (5 min) liegt, hat der SQL-Code wenig Speicher. Sammeln Sie außerdem Datenträgerindikatoren: Länge der Warteschlange , Datenträgerzeit (Ihr Datendateilaufwerk), Datenträgerzeit (Ihr Protokolldateilaufwerk), um festzustellen, ob die Datenträger unter Druck stehen.
yrushka
quelle
5

Versuchen Sie es mit:

SET STATISTICS IO ON

und

SET STATISTICS PROFILE ON

STATISTIKEN IO

Kann hilfreich sein, um Ihnen mitzuteilen, welche Tabellen die meisten Tabellensuchen, logischen Lesevorgänge 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

Wird der Abfrageplan in erster Linie in tabellarischer Form zurückgegeben, können Sie in den E / A- und CPU-Spalten nachsehen, was die Abfrage am meisten kostet Clustered Key, etc ...)

Andrew Bickerton
quelle