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.