Eine Abfrage wie die folgende, die garantiert keine Zeilen zurückgibt, dauert auf einem unserer Server zwischen 0 und 160 Sekunden:
select col1, col2, col3
from tab1
where 0 = 1
Vor zwei Wochen geschah dies sechsmal im Abstand von 48 Stunden. Letzte Woche dauerte die gleiche Abfrage ~ 0 Sekunden. Ich habe Protokolle der SQLs unserer Anwendung, aber noch keine Verdächtigen gefunden. Außerdem dachte ich, dass eine Abfrage vom Typ 0 / wobei 0 = 1 niemals die Datenseiten trifft, also sollte sie gegen Datensperren auf Zeilen- / Seiten- / Tabellenebene resistent sein? Das Schema wird von keinen (bekannten) SQLs berührt.
Da das Problem nicht konsistent ist und der Server sehr stark ausgelastet ist, möchte ich die Theorie hinter dem Geschehen verstehen, bevor ich den SQL-Profiler anhänge. Andere Abfragen werden während dieser Verzögerungen problemlos ausgeführt. Ein bekanntes Problem in der Anwendung ist eine hohe Anzahl dynamisch erstellter SQL-Abfragen - etwa 200.000 eindeutige Abfragen mit insgesamt 850.000 (protokollierten) Abfragen über einen Zeitraum von 48 Stunden. Kann dies zu solchen Problemen führen?
Auf dem Server wird SQL Server 2005 Standard Edition, 96 GB RAM, Festplatten im SAN und 4 CPUs / 16 Kerne ausgeführt. Datenbankdateien und Dateigruppen sind gut optimiert und sollten kein Problem darstellen (wir untersuchen dies jedoch separat).
Alle Hinweise, wo zu suchen, wird sehr geschätzt.
Edit: Perfekt! Die Abfrage wurde wiederholt, um den Ausführungsplan hinzuzufügen, und es dauerte 1 Minute und 35 Sekunden. Hier ist der Ausführungsplan und der Screenshot mit der Abfragedauer:
Bearbeiten 2: Details zur Statistikzeit für einen zweiten Lauf. Scheint momentan konstant langsam zu sein, daher werden wir Profiler und Perfmon anhängen:
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 97402 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
quelle
Antworten:
Es scheint, als ob selbst mit einer
... WHERE 0 = 1
Klausel weiterhin eine Absichtssperre (IS
) für die Tabelle erforderlich ist . Lassen Sie uns dies beweisen:Ich werde zunächst eine Testtabelle erstellen:
Nachdem ich meine Testtabelle habe, werde ich in einer Sitzung (Abfragefenster) Folgendes ausführen, um eine exklusive (
X
) Sperre zu aktivierendbo.MyTestTable1
:Ich kann die exklusive Sperre anhand der
sys.dm_tran_locks
DMV überprüfen . Dann mache ich in einer anderen Sitzung (neues Abfragefenster) genau das, was Ihre Abfrage macht:Auf den ersten Blick sehe ich, dass es nicht abgeschlossen ist. Beim Betrachten
sys.dm_exec_requests
sehe ich genau, warum dies der Fall ist:Ich kann hier sehen, dass meine
... WHERE 0 = 1
Abfrage auf eineIS
Sperre für dieses Objekt wartet (die object_id übersetzt indbo.MyTestTable1
).Ich sage keineswegs, dass Parallelität Ihr Problem ist, aber durch die Geräusche zeigen Sie die Symptome. Das obige Beispiel soll beweisen, dass Sie auch mit einer
WHERE
Klausel, die niemals Daten zurückgibt, nicht vom Sperren und Blockieren befreit sind .Alles, was wir tun können, ist zu raten. Wenn es also "lange dauert", müssen Sie genau sehen, was diese Anfrage tut, die so lange dauert. Wenn es auf etwas wartet, dann sehen Sie, worauf es wartet.
quelle
Abhängig davon, wie stachelig und threadsicher Ihre Abfragen sind, stellt Ihr System diese Abfrage möglicherweise einfach in die Warteschlange. Die Standardanzahl der Worker (dh die Anzahl der gleichzeitigen SQL Server-Threads) für Ihr Setup sollte etwa 700 betragen.
Überprüfen Sie sys.dm_os_schedulers und sys.dm_os_waiting_tasks, um festzustellen, ob dies ein Problem sein könnte.
quelle