Plötzlicher Leistungsabfall von SQL Server

13

Ich habe einen SQL Server 2005, der in letzter Zeit unvorhersehbar geworden ist, und ich kratzte mir am Kopf, warum. Abfragen, die in Sekunden ausgeführt werden, ändern Pläne und dauern Minuten (Zeit in vollem Tabellenscan oder Index-Spool). Das erste und offensichtlichste ist, dass die Statistiken veraltet sind und das Optimierungsprogramm dadurch verwirrt wird. Ich bin jedoch überzeugt, dass dies nicht der Fall ist. Erstens, weil sich die zugrunde liegenden Daten nicht wesentlich ändern (z. B. Hinzufügen von Daten eines Tages zu Daten eines Jahres) bereits in einer Tabelle) und zweitens, weil Auto Create Statistics und Auto Update Statistics beide wahr sind. Der Optimierer wird jedoch verwirrt. Das Ausführen von SQL im Tuning Advisor gibt mir viele mehrspaltige CREATE STATISTICSAnweisungen, die es zu beheben scheinen (bis sich das nächste bisschen SQL falsch verhält).

Irgendwelche Ideen einer Strategie, mit der ich mich der Ursache dieses Problems nähern kann? Warum reichen die "normalen" Statistiken nicht aus?

Gaius
quelle

Antworten:

8

Wenn Sie am häufigsten auf SOS_SCHEDULER_YIELD warten, haben Sie anscheinend etwas Druck auf die CPU. Dies kann aber auch darauf zurückzuführen sein, dass Ihr Design für Ihre Abfragen nicht mehr ausreicht. Ich weiß, dass Sie gesagt haben, dass Sie nur die Daten eines Tages hinzufügen, aber Sie hätten einen Wendepunkt erreichen können.

Wie werden Ihre Anfragen gestellt? Ist es dynamisches SQL? Verwenden Sie gespeicherte Prozeduren? Verwenden Sie sp_executesql? Ist es möglich, dass Sie an Parametern schnüffeln? Wie sieht Ihr DB-Design aus? Was sind die PK- und FK-Beziehungen?

Haben Sie ein Beispiel für einen guten Plan? Wenn Sie in der Lage sind, einen guten Plan zu ermitteln, können Sie Plananleitungen verwenden, um die Ausführung der Abfrage auf eine bestimmte Weise zu erzwingen.

Können Sie ein Beispiel für einen schlechten Plan geben?

Holen Sie sich zum Schluss eine Kopie von sp_whoIsActive ( http://whoisactive.com/ ) von Adam Machanic und ermitteln Sie anhand dieser Informationen, welche Abfragen ausgeführt werden. Und wenn Sie die Ausgabe von sp_whoIsActive erfassen möchten, klicken Sie hier http://www.littlekendra.com/2011/02/01/whoisactive/

SQLRockstar
quelle
Es ist eine Drittanbieteranwendung, ich habe keine Kontrolle über das Schema oder SQL, was ziemlich schrecklich ist, viele parametrisierte Abfragen (z. B. where col=(cast @var...)) und sein @varkönnte '%'. Ich habe es erst vor ein oder zwei Wochen geerbt und muss es im Grunde so lange funktionieren lassen, bis es ersetzt wird. Danke für den Link, ich werde es versuchen.
Gaius
Das zweitgrößte Warten danach SOS_SCHEDULER_YIELDwar CXPACKETund sp_configure "max degree of parallelism", 1scheint - vorerst - beide Probleme auf den Kopf geschlagen zu haben. Vielen Dank!
Gaius
+1 für den Link zu sp_whoIsActive
Jeff
8

Von MSDN :

" Insert Operationen treten auf aufsteigend oder absteigend Schlüsselspalten Statistik auf- oder Schlüsselspalten absteigend, wie Identität oder Echtzeit - timestamp - Spalten, könnten häufigere Aktualisierungen der Statistiken als die Abfrageoptimierer führt erfordern. Insert - Operationen neue Werte auf- oder absteigenden Spalten anhängen Die Anzahl der hinzugefügten Zeilen ist möglicherweise zu gering, um eine Statistikaktualisierung auszulösen.Wenn die Statistiken nicht aktuell sind und Abfragen aus den zuletzt hinzugefügten Zeilen ausgewählt werden, werden für die aktuellen Statistiken keine Kardinalitätsschätzungen für diese neuen Werte erstellt Dies führt zu ungenauen Schätzungen der Kardinalität und einer langsamen Abfrageleistung.

Beispielsweise enthält eine Abfrage, die aus den letzten Auftragsterminen auswählt, ungenaue Kardinalitätsschätzungen, wenn die Statistiken nicht aktualisiert werden, um Kardinalitätsschätzungen für die letzten Auftragstermine zu enthalten.

Nach Wartungsvorgängen Nach Durchführung von Wartungsvorgängen, die die Verteilung von Daten ändern, wie z. B. Abschneiden einer Tabelle oder Masseneinfügung eines großen Prozentsatzes der Zeilen, sollten Sie die Statistiken aktualisieren. Dies kann zukünftige Verzögerungen bei der Abfrageverarbeitung vermeiden, während Abfragen auf automatische Statistikaktualisierungen warten. "

Sie können von Zeit zu Zeit "EXEC sp_updatestats" auf Ihrem System verwenden (geplant) oder die Funktion STATS_DATE für alle Objekte verwenden, um zu sehen, wann ihre Statistiken das letzte Mal aktualisiert wurden und ob seitdem zu viel Zeit vergangen ist. Verwenden Sie UPDATE STATISTIKEN für dieses bestimmte Objekt. Meiner Erfahrung nach sind wir auch mit aktivierter automatischer Statistik gezwungen, die Statistiken von Zeit zu Zeit zu aktualisieren, da Einfügevorgänge keine automatische Aktualisierung ausgelöst haben.

So fügen Sie meinen persönlichen Code hinzu (der in einem wöchentlichen Job verwendet wird, der dynamische Anweisungen für die Aktualisierung von Statistiken erstellt):

select distinct
        'update statistics [' + stats.SchemaName + '].[' + stats.TableName + ']'
            + case when stats.RowCnt > 50000 then ' with sample 30 percent;'
            else 
                ';' end
        as UpdateStatement
    from (
        select
            ss.name SchemaName,
            so.name TableName,
            so.id ObjectId,
            st.name AS StatsName, 
            STATS_DATE(st.object_id, st.stats_id) AS LastStatisticsUpdateDate
            , si.RowModCtr
            , (select case si2.RowCnt when 0 then 1 else si2.RowCnt end from sysindexes si2 where si2.id = si.id and si2.indid in (0,1)) RowCnt
        from sys.stats st
            join sysindexes si on st.object_id = si.id and st.stats_id = si.indid
            join sysobjects so on so.id = si.id and so.xtype = 'U' --user table
            join sys.schemas ss on ss.schema_id = so.uid
    ) stats
    where cast(stats.RowModCtr as float)/cast(stats.RowCnt as FLOAT)*100 >= 10 --more than 10% of the rows have changed
    or ( --update statistics that were not updated for more than 3 months (and rows no > 0)
        datediff(month, stats.LastStatisticsUpdateDate, getdate()) >= 3
        and stats.RowCnt > 0
    )

Hier bekomme ich alle Objekte, bei denen die Statistiken länger als 3 Monate nicht aktualisiert wurden oder bei denen sich seit der letzten Aktualisierung der Statistiken mehr als 10% der Zeilen geändert haben.

Marian
quelle
Hmm, mein wichtigstes Warteereignis ist, SOS_SCHEDULER_YIELDaber ich kann momentan nicht sagen, ob das an den schlechten Plänen liegt oder ob diese (6-jährige, 2-Prozessor, 4G RAM) Box jetzt wirklich nur überlastet ist und ich habe über einen Wendepunkt gegangen.
Gaius
Anstatt nur diese Abfrage auszuführen, um die UPDATE-Anweisungen zu erstellen, und sie manuell auszuführen, können Sie einen Cursor verwenden, der auf dieser select-Anweisung basiert, um die Ergebnisse mit Aufrufen von sp_executesql zu durchlaufen. Auf diese Weise können Sie sie automatisch ausführen (zum Beispiel als Teil) eines Wartungsplans über Nacht (oder in einer anderen ruhigen Zeit).
David Spillett
@David: das mache ich im wöchentlichen job :). Ich habe es nur anders formatiert, damit Gaius die Ausgabe sieht, die ich benutze. Das anfängliche Drehbuch war viel zu hässlich und lang. Vielen Dank für die Hilfe bei der Formatierung! Kannst du mir ein Formatierungs-Tutorial schicken? Vielen Dank!
Marian
Es gibt einen Link "Formatierungshilfe" auf dem Bildschirm "Antwort bearbeiten" und ein Symbol rechts über dem Feld für die Erstantwort auf der Hauptfrageseite, das die von diesen Sites unterstützte Abschriftensyntax auflistet.
David Spillett
3
Die Statistik für die automatische Aktualisierung wird bei 20% + 500 Zeilen und nicht bei 10% ausgelöst.
Mrdenny
3

Ich gehe davon aus, dass eine oder mehrere Ihrer Tabellen so groß werden, dass sie nicht die 20% der Änderungen erreichen, die erforderlich sind, um die aktuelle Statistik als veraltet zu kennzeichnen, sodass die automatische Aktualisierung der Statistiken aktiviert wird und es dennoch genügend Aktualisierungen (oder Einfügungen) gibt ), dass die Aktualisierung der Statistiken sehr hilfreich wäre. Das Gleiche habe ich kürzlich in einer bestimmten Umgebung nach dem Upgrade von SQL 2000 auf SQL 2008 gefunden.

Zusätzlich zu den anderen Sites, die in den Antworten oben erwähnt wurden, würde ich vorschlagen, die folgenden Online-Ressourcen zu prüfen.

1) Red-Gate stellt eine Reihe kostenloser eBooks zum Download zur Verfügung, darunter "SQL Server Statistics" von Holger Schmeling. Dort finden Sie das folgende Zitat:

http://www.red-gate.com/our-company/about/book-store/

"Tabellen mit mehr als 500 Zeilen und mindestens 20% der Daten einer Spalte mussten geändert werden, um verknüpfte Statistiken ungültig zu machen."

2) SQL Sentry verfügt über ein kostenloses Plan-Explorer-Tool, mit dessen Hilfe Probleme in einem SQL-Plan aufgespürt werden können, z. B. eine Schätzung von zu vielen oder zu wenigen Zeilen im Vergleich zur tatsächlichen Anzahl von Zeilen für eine bestimmte Tabelle in einer Abfrage. Speichern Sie einfach den tatsächlichen Ausführungsplan in SSMS und durchlaufen Sie die verschiedenen Teile des Plans mit Plan Explorer. Es ist nicht so, dass die Informationen in SSMS mithilfe des grafischen Ausführungsplans nicht verfügbar sind, aber das Tool von SQL Sentry erleichtert die Anzeige erheblich.

http://www.sqlsentry.com/plan-explorer/sql-server-query-view.asp

3) Überprüfen Sie das Aktualisierungsdatum der Statistiken selbst auf Tabellen in den Abfragen, an denen Sie mit STATS_DATE () am meisten interessiert sind. Sie können eine schnelle Abfrage finden, um die ältesten Statistiken mit einer Abfrage zu erhalten, die in der folgenden Diskussion zu finden ist.

http://blog.sqlauthority.com/2010/01/25/sql-server-find-statistics-update-date-update-statistics/

Ich hoffe das hilft!

Ich denke, Sie werden das Buch von Red-Gate besonders genießen!

-Jeff

Jeff
quelle
Danke, ich arbeite mich durch diese. Ich bin hauptsächlich ein Oracle-Datenbankadministrator, der dieses System geerbt hat (obwohl ich überhaupt keine Vorurteile gegenüber SQL Server habe, was ich seit 2005 sehe, ist es eine sehr leistungsfähige Plattform, ich kenne es einfach nicht so gut wie Oracle). .
Gaius