Die Umgebung:
Wir haben zwei 32-Bit-Windows Server 2003 R2-Computer, auf denen SQL Server 2005 ausgeführt wird. Die Hardwarekonfigurationen sind identische Server mit Xeon 5160-CPU, 4 GB RAM und 13 GB RAID0. AWE- und / 3GB-Flags sind nicht aktiviert.
Die Server wurden mithilfe einer vordefinierten Installationscheckliste nebeneinander eingerichtet, und ALLE installierte Software ist auf beiden Computern gleich.
Alle SQL Server-Installationseinstellungen und Patch-Levels, die wir überprüfen müssen, sind identisch. Ein Unterschied besteht darin, dass TEMPDB auf dem schnellen Computer 400 MB und auf dem langsamen Computer 1,2 GB beträgt. In beiden Fällen sehen wir jedoch keine TEMPDB-Zuweisung.
Das Problem:
Es gibt eine gespeicherte Prozedur, die in zwei Sekunden auf der einen, aber in 15 Minuten auf der anderen Seite ausgeführt wird. Während der zusätzlichen 15 Minuten gibt es wenig bis gar keine Festplattenaktivität, keine Änderungen der Speichernutzung, aber ein CPU-Kern ist die ganze Zeit über zu 100% gepinnt.
Dieses Verhalten bleibt auch dann bestehen, wenn die Datenbanken von einer gesichert und auf der anderen wiederhergestellt werden.
Da es sich um eine gespeicherte Prozedur handelt, zeigen der Aktivitätsmonitor und der Profiler keine Details darüber an, wo in der gespeicherten Prozedur diese hohe CPU-Aktivität stattfindet.
Die Frage:
Worauf sollten wir noch achten?
Nachverfolgen:
Die Langsamkeit tritt in den FETCH NEXT-Anweisungen für die folgende Cursordefinition auf:
DECLARE C CURSOR FOR
SELECT X, Y
FROM dbo.A
WHERE X NOT IN (SELECT X FROM dbo.B)
AND Z <=0
...
<snip>
...
FETCH NEXT FROM C INTO @X, @Y
FETCH NEXT FROM C INTO @X, @Y
...
Jede der FETCH-Anweisungen - für eine Tabelle mit nur etwa 1000 Zeilen - benötigt etwa 7,25 Minuten. (Nein, ich weiß nicht, warum es zwei in einer Reihe macht, muss die Entwickler fragen, aber es läuft korrekt auf beiden Servern).
Ich bin etwas misstrauisch gegenüber "NOT IN (SELECT ...)", da es so aussieht, als ob Virtual Reads sehr hoch ist.
quelle
Antworten:
Wenn Sie eine Methode zur Fehlerbehebung bei der Leistung wie Wartezeiten und Warteschlangen verwenden, um den Grund für den hohen CPU-Verbrauch zu ermitteln, können Sie geeignete Maßnahmen empfehlen, sobald der Engpass identifiziert ist.
quelle
SQL Server wählt einen anderen Plan für das andere Feld aus.
Durch das Wiederherstellen werden in der Regel Probleme auf der Grundlage von Statistiken behoben, sodass ich die Serverunterschiede untersuchen würde.
Einige grobe Kontrollen zuerst. Gehen Sie nicht davon aus: Überprüfen Sie
Dann springe auf das tiefe Ende, wie Remus antwortete.
quelle
Wenn alle anderen Dinge gleich sind, wird wahrscheinlich (gemäß der Antwort von @ gbn) auf jedem Server ein anderer Ausführungsplan generiert. Als akademische Übung wäre es interessant, beide Pläne zu sehen. Nehmen Sie sie also aus dem Plan-Cache auf jedem Server und fügen Sie sie, wenn möglich, Ihrer Frage hinzu. Wir können dann die Unterschiede in den Plänen identifizieren, die zu so großen Leistungsunterschieden führen.
Schauen Sie sich für eine schnelle Lösung den USE PLAN-Hinweis an . Dadurch ist es möglich, den guten Plan vom schnellen Server an die gespeicherte Prozedur auf dem langsamen Server anzuhängen.
Bearbeiten: Nach Aktualisierung des Cursors
Eine weitere Variation Ihrer Anfrage, die ich in anderen Antworten nicht finden kann:
quelle
Humor mich, und versuchen Sie zu ersetzen:
mit diesem:
Ich denke nicht, dass sich dies als Leistungsproblem im Abschnitt FETCH NEXT FROM Ihres Codes manifestieren sollte, aber ich habe noch keine Koffeininjektion erhalten. Probieren Sie meinen Vorschlag aus und lassen Sie es mich wissen.
Hoffe das hilft,
Matt
quelle
Überprüfen Sie Ihre Indizes und aktualisieren Sie alle Ihre Statistiken. Ich hatte ein sehr ähnliches Problem und es stellte sich heraus, dass die Statistiken auf einer Maschine fehlerhaft waren.
quelle
Ich habe dasselbe Verhalten zweimal erlebt und werde Ihnen jedes Mal sagen, was es behoben hat:
1.) Ich habe den Hinweis WITH RECOMPILE zur gespeicherten Prozedur hinzugefügt, weil der zwischengespeicherte Plan schrecklich war.
2.) Ich habe die gespeicherte Prozedur geändert, um temporäre Tabellen anstelle von Tabellenvariablen zu verwenden.
Ich hoffe, dass diese beiden helfen. Viel Glück.
quelle