Optimierung der SQL-Datenbankleistung


7

Wir haben eine schreibintensive SQL-Datenbank (SQL Server 2008) und die Einfügegeschwindigkeit nimmt nach einiger Zeit ab. Ich habe diese ähnlichen Fragen gelesen: SQL Insert Speed , SQL: Was verlangsamt INSERTs, wenn nicht CPU oder IO? und INSERTs beschleunigen .

Außerdem habe ich diesen Beitrag über die Analyse der SQL Server-Leistung gelesen, der mir dabei half, Engpässe zu finden (z. B. durch Abfragen sys.dm_exec_requestsund sys.dm_os_wait_stats), aber ich habe immer noch Schwierigkeiten, die Abfrageergebnisse zu interpretieren und das Problem zu beheben.

Zuerst begann ich mit der Abfrage der, sys.dm_exec_requestsdie nur eine Sitzungs-ID (Auswahlabfrage) mit dem Status "running" zurückgab (dh ich fand KEINE SUSPENDED SESSIONS). Also, wenn nichts meine Beilage blockiert hat, warum wird es langsam?

Als nächstes habe ich sys.dm_os_wait_statsStatistiken über alle Wartetypen überprüft. Das Ergebnis zeigte, dass LATCH_EX, CXPACKET UND PAGEIOLATCH_SH die meiste Wartezeit hatten (694379 ms, 310364 ms bzw. 308335 ms).

Dann fand ich sys.dm_os_latch_statsden am weitesten verbreiteten Verriegelungstyp, der in meinem Fall war ACCESS_METHODS_DATASET_PARENT.

  • Erstens weiß ich nicht, wie ich die Abfrage für jede Sitzungs-ID in den Ergebnissen der Abfrage finden kann sys.dm_exec_requests.
  • Zweitens, wie viele Wartezeiten (in sys.dm_os_wait_stats) sollten als hoch angesehen werden? Und wenn die oben genannten Zahlen (Ergebnisse von sys.dm_os_wait_stats) hoch sind, wie kann ich sie verringern?
  • Soweit ich weiß, ACCESS_METHODS_DATASET_PARENThängt dies mit Parallelität zusammen, und eine der Lösungen, die ich gefunden habe, war die Verringerung des Parallelitätsgrades. Ist das richtig?
  • In MySQL gibt es einige Tunning-Einstellungen, die direkt nach der Installation vorgenommen werden können (z. B. Erhöhen der Größe des Innodb-Pufferpools). Gibt es in SQL Server etwas Ähnliches?

Noch ein paar Infos:

  • Bei Verwendung sys.dm_db_index_usage_statsbeträgt die Anzahl der Lese- und Schreibvorgänge 80336 bzw. 70672.

  • Eine unserer am stärksten ausgelasteten Tabellen ist trans_all(mit allen Zahlungsvorgängen) ohne TRIGGERS, NO CONSTRAINTS (dies ist für alle Tabellen gleich), hat jedoch einen CLUSTERED INDEX, der PK_trans_all aus den folgenden Spalten besteht: gs_id (smallint), pt_id (tinyint), tanking_time (datetime), purchase_type (tinyint).

  • Die Datenbankgröße beträgt 2,6 GB und die trans_allTabellengröße 155 MB.

UPDATE_1

In Bezug auf die habe ACCESS_METHODS_DATASET_PARENTich die Lösung ausprobiert, die ich gefunden habe (dh den Grad der Parallelität geändert. Ich habe sie in 1 geändert, um sicherzustellen, dass die Abfrage niemals zur Parallelität wechselt), aber das Problem wurde dadurch nicht behoben: | soll ich es nochmal ändern Was ist die Standardeinstellung, die ich verwenden soll?

UPDATE_2

Ich habe gerade die Größe der Transaktionsprotokolldatei für meine Datenbank überprüft, die 2,4 GB beträgt, und der verwendete% Protokollspeicher beträgt 98%. Könnte dies der Grund sein, meine Einsätze zu verlangsamen? Sollte ich die Größe der Protokolldatei erhöhen?

Außerdem habe ich sys.database_filesdie Dateigröße und den leeren Speicherplatz für meine Datenbank überprüft. Das Ergebnis zeigt, dass die Dateigröße 195 MB und der leere Speicherplatz 0,187 MB beträgt .


Ich habe immer festgestellt, dass sp_WhoIsActive sqlblog.com/files/folders/release/tags/who+is+active/… hervorragend für eine kurze Momentaufnahme der Vorgänge geeignet ist, ohne DMVs durchsuchen zu müssen. Wo beobachten Sie, dass die Einfügegeschwindigkeit abnimmt? Hast du eine Frontend App? Oder ein Datenlogger? Wenn ein Datenlogger, wie meldet er eine Abnahme der Einfügegeschwindigkeit? Aus Ihrer Beschreibung geht hervor, dass viele Clients häufig kleine Datensätze einfügen und nicht viele große Massendaten einfügen.
Nick.McDermaid

1
Meine Vermutung wäre, dass Ihr Clustered-Index für viele Spalten die Dinge verlangsamt, da Sie nicht in den freien und freien Bereich am Ende der Tabelle einfügen, sondern in bereits ausgelastete Seiten in der Mitte. Ich würde wahrscheinlich empfehlen, den Clustered-Index für diese Tabelle in eine einfache inkrementierende ID zu ändern und Ihren vorhandenen Index bei Bedarf in einen einfachen, nicht gruppierten Index zu verschieben. Aber dba wäre ein besserer Ort, um zu fragen, ich würde sagen ...
Matt Gibson

@ MattGibson die Einfügungen sind am Ende der Tabellen
Monamona

1
Ist das die genaue Reihenfolge, in der Ihr Clustered-Index in ( gs_id, pt_id, fueling_time, purchase_type) definiert ist ? Wenn ja, gehe ich davon aus, dass sich die Einfügungen nicht am Ende der Tabellen befinden, wie Sie gesagt haben, und dass während Ihrer Einfügungen eine große Anzahl von Seitenteilen auftritt.
GarethD

Messen Sie die Fragmentierung. Ist das Einfügen nach der Defragmentierung schneller?
Paparazzo

Antworten:


2

Es gibt viele Faktoren, die diese Verlangsamung der Einsätze verursachen können, wie Sie beschrieben haben.

Etwas, das ich in Ihren Informationen nicht sehe, ist die Datenbank- / Tabellengröße, in die die Einfügungen gehen. Je größer die Tabelle wird, desto länger dauern Ihre Einfügungen aufgrund der Tabellengröße, der Fragmentierung und des Schreibens derselben Daten in Ihre Indizes.

Die DM-Abfragen, die Sie ausführen, haben Ihnen einige gute Informationen gegeben. Ich würde auch empfehlen, das Toolkit von Brent Ozar zu verwenden. Verknüpfung

Ich würde vorschlagen, dass Sie SP_BlitzIndex und SP_BlitzCache verwenden. Diese geben Ihnen einen weiteren Überblick darüber, was tatsächlich in der Datenbank geschieht und was die von Ihnen ausgeführten Einfügeabfragen zu diesem Zeitpunkt tun.

Ich würde auch überprüfen, wann das letzte Mal eine DBCC-CHECKDB ausgeführt wurde und wann Sie Ihre Indizes und Statistiken zuletzt neu erstellt haben.

Vielen Dank für die Updates, siehe unten:

Noch ein paar Infos:

Nicht viel Lesen / Schreiben, also bin ich nicht zu besorgt.

Wissen Sie, wann der trans_all-Index das letzte Mal neu erstellt wurde? Wenn Sie nur einen Deckungsindex und viele Einfügungen haben, dauert das Einfügen von Daten jedes Mal länger, wenn diese veraltet sind. Im Folgenden finden Sie eine Abfrage zum Überprüfen der Fragmentierung Ihrer Datenbanktabellen:

Use <Database>
GO

SELECT OBJECT_NAME(ind.OBJECT_ID) AS TableName, 
ind.name AS IndexName, indexstats.index_type_desc AS IndexType, 
indexstats.avg_fragmentation_in_percent 
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, NULL) indexstats 
INNER JOIN sys.indexes ind  
ON ind.object_id = indexstats.object_id 
AND ind.index_id = indexstats.index_id 
WHERE indexstats.avg_fragmentation_in_percent > 30 
ORDER BY indexstats.avg_fragmentation_in_percent DESC

UPDATE 1:

MAX DOP-Einstellungen können sich auf Ihre Abfragelaufzeit auswirken, aber ich kann nicht sicher sein, ob dies der Fall ist, ohne die von Ihnen verwendete Abfrage zu sehen und dann die geschätzten Planergebnisse zu überprüfen, um festzustellen, was SQL Server verwendet. Es gibt zwei Statistiken, mit denen Sie herausfinden können, wie die Abfrage beim Anpassen des MAX DOP beeinflusst wird.

SET STATISTICS IO ON;
SET STATISTICS TIME ON;
GO

Hier sind einige Informationen von Kendra Little bei Brent Ozar, wie Sie diese verwenden können, um Ihnen Richtlinien zu geben.

tsql-Measure-Performance-Verbesserungen

und

q-can-high-maxdop-make-a-query-langsamer

UPDATE 2:

Ich würde empfehlen, die Protokollgröße zu erhöhen, wenn sie zu 98% voll ist. Fügen Sie entweder ein weiteres Protokoll hinzu oder erhöhen Sie es. Sie können sich auch TEMP_DB ansehen und sehen, was es tut, weil SQL dies als Speicherplatz für viele Dinge verwendet.

Leerer Raum ist kein wirkliches Problem, es sei denn, Sie haben keinen Platz mehr zum Wachsen. Es sagt Ihnen nur, wie viel Platz bis zum nächsten automatischen Wachstum übrig bleibt.


Danke für deine Antwort. Glauben Sie also, dass das Problem nicht mit dem Grad der Parallelität zusammenhängt? (da ich ACCESS_METHODS_DATASET_PARENTals Ergebnis von gesehen habe sys.dm_os_latch_stats? Ich meine, wenn es nicht das Problem war, warum ich dmv verwenden musste?
Monamona

0

Wenn Ihre Datenbank per Protokoll versendet wird, kann es sein, dass das Protokoll mit Transaktionen gefüllt wird. Warten Sie dann bis zur nächsten Protokollsicherung, bevor Sie sie bereinigen und Platz für neue Transaktionen schaffen, um die Verarbeitung fortzusetzen. Versuchen Sie, die Lücke zwischen den Versandperioden des Protokolls zu verringern oder die Größe der Protokolldatei zu erhöhen. Es gibt noch andere Dinge, die Sie tun können, wie das Überprüfen der Indexnutzungsstatistiken und das Entfernen nicht verwendeter Indizes. Ihre Wartung führt zu zusätzlichen Anforderungen an das Protokoll.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.