Ich habe eine Prozedur gespeichert, die jedes Mal, wenn sie von der Webanwendung aufgerufen wird, eine wahnsinnige Zeitüberschreitung aufweist.
Ich habe den SQL-Profiler gestartet und die Anrufe in dieser Zeit verfolgt und schließlich Folgendes herausgefunden:
- Bei der Ausführung der Anweisungen aus dem MS SQL Management Studio mit denselben Argumenten (tatsächlich habe ich den Prozeduraufruf aus dem SQL-Profil-Trace kopiert und ausgeführt): Der Vorgang dauert durchschnittlich 5 bis 6 Sekunden.
- Wenn es von einer Webanwendung aufgerufen wird, dauert es mehr als 30 Sekunden (in Trace), sodass meine Webseite bis dahin tatsächlich eine Zeitüberschreitung aufweist.
Abgesehen von der Tatsache, dass meine Webanwendung einen eigenen Benutzer hat, ist alles gleich (dieselbe Datenbank, Verbindung, Server usw.). Ich habe auch versucht, die Abfrage direkt im Studio mit dem Benutzer der Webanwendung auszuführen, und es dauert nicht mehr als 6 sek.
Wie finde ich heraus, was passiert?
Ich gehe davon aus, dass dies nichts mit der Tatsache zu tun hat, dass wir BLL> DAL-Schichten oder Tabellenadapter verwenden, da die Kurve deutlich zeigt, dass die Verzögerung im tatsächlichen Verfahren liegt. Das ist alles woran ich denken kann.
BEARBEITEN Ich habe in diesem Link herausgefunden, dass ADO.NET ARITHABORT
auf true gesetzt ist - was für die meiste Zeit gut ist, aber manchmal passiert dies, und die vorgeschlagene Problemumgehung besteht darin with recompile
, dem gespeicherten Prozess eine Option hinzuzufügen . In meinem Fall funktioniert es nicht, aber ich vermute, es ist etwas sehr Ähnliches. Weiß jemand, was ADO.NET sonst noch macht oder wo ich die Spezifikation finden kann?
quelle
Antworten:
In der Vergangenheit ist ein ähnliches Problem aufgetreten, daher bin ich gespannt auf eine Lösung für diese Frage. Aaron Bertrands Kommentar zum OP führte zu einer Zeitüberschreitung bei Abfragen , wenn er über das Web ausgeführt wurde, aber superschnell, wenn er über SSMS ausgeführt wurde. Obwohl die Frage kein Duplikat ist, kann die Antwort durchaus auf Ihre Situation zutreffen.
Im Wesentlichen klingt es so, als hätte SQL Server möglicherweise einen beschädigten zwischengespeicherten Ausführungsplan. Sie treffen mit Ihrem Webserver auf den schlechten Plan, aber SSMS landet auf einem anderen Plan, da das ARITHABORT-Flag eine andere Einstellung aufweist (die sonst keine Auswirkungen auf Ihre bestimmte Abfrage / Ihren gespeicherten Prozess hätte).
Siehe ADO.NET, das die gespeicherte T-SQL-Prozedur aufruft, verursacht eine SqlTimeoutException für ein anderes Beispiel mit einer vollständigeren Erklärung und Auflösung.
quelle
DBCC DROPCLEANBUFFERS
undDBCC FREEPROCCACHE
den Trick gemacht! Ich vermute, der Ausführungsplan war irgendwie beschädigt oder nicht aktualisiert. Ich bin zweifelhaft, dass es sich um eine dauerhafte Lösung handelt. Wenn sie einmal beschädigt werden könnte, könnte sie es erneut tun. Ich beschäftige mich also immer noch mit den plausiblen Ursachen. Da die Web-App wieder funktioniert, muss ich den Druck nicht spüren. Vielen Dank.OPTIMIZE FOR
oderOPTION(Recompile)
abzufragen, die Probleme verursachen. Dieser Artikel beschreibt das Problem ausführlich. Wenn Entity Framework Ihre Abfragen generiert, bietet dieser Beitrag eine Möglichkeit, Ihren Abfragen einen Abfragehinweis hinzuzufügen.Ich habe auch festgestellt, dass Abfragen in SSMS langsam aus dem Web und schnell ausgeführt wurden, und ich fand schließlich heraus, dass das Problem ein sogenanntes Parameter-Sniffing war.
Die Lösung für mich bestand darin, alle im sproc verwendeten Parameter in lokale Variablen zu ändern.
z.B. Veränderung:
zu:
Scheint seltsam, aber es hat mein Problem behoben.
quelle
Nicht um Spam zu versenden, aber als hoffentlich hilfreiche Lösung für andere hat unser System ein hohes Maß an Zeitüberschreitungen festgestellt.
Ich habe versucht, die gespeicherte Prozedur so einzustellen, dass sie mithilfe von neu kompiliert wird.
sp_recompile
Dadurch wurde das Problem für den einen SP behoben.Letztendlich gab es eine größere Anzahl von SPs, bei denen eine Zeitüberschreitung auftrat , von denen viele dies noch nie zuvor getan hatten,
DBCC DROPCLEANBUFFERS
undDBBC FREEPROCCACHE
die Häufigkeit von Zeitüberschreitungen bei Vorfällen ist erheblich gesunken - es gibt immer noch vereinzelte Vorkommnisse, von denen ich vermute, dass die Planregeneration stattfindet eine Weile, und einige, in denen die SPs wirklich unterdurchschnittlich sind und eine Neubewertung benötigen.quelle
DBCC DROPCLEANBUFFERS
undDBCC FREEPROCCACHE
keinen Unterschied machte.Könnte es sein, dass einige andere DB-Aufrufe, die vor dem Aufruf der Webanwendung durch den SP ausgeführt werden, eine Transaktion offen halten? Dies könnte ein Grund dafür sein, dass dieser SP wartet, wenn er von der Webanwendung aufgerufen wird. Ich sage, isolieren Sie den Aufruf in der Webanwendung (stellen Sie ihn auf eine neue Seite), um sicherzustellen, dass eine vorherige Aktion in der Webanwendung dieses Problem verursacht.
quelle
Das einfache Neukompilieren der gespeicherten Prozedur (in meinem Fall die Tabellenfunktion) hat bei mir funktioniert
quelle
Wie @Zane sagte, könnte es an Parameter-Sniffing liegen. Ich habe das gleiche Verhalten erlebt und mir den Ausführungsplan der Prozedur und alle Anweisungen des sp in einer Reihe angesehen (alle Anweisungen der Prozedur kopiert, die Parameter als Variablen deklariert und die gleichen Werte für die Variable als zugewiesen die Parameter hatten). Der Ausführungsplan sah jedoch völlig anders aus. Die Ausführung von sp dauerte 3-4 Sekunden und die Anweisungen in einer Reihe mit genau den gleichen Werten wurden sofort zurückgegeben.
Nach einigem googeln fand ich eine interessante Lektüre über dieses Verhalten: Langsam in der Anwendung, Schnell in SSMS?
Das Problem war, dass ich Parameter hatte, die null gelassen werden konnten, und wenn sie als null übergeben wurden, wurden sie mit einem Standardwert initialisiert.
Nachdem ich es geändert habe
es funktionierte wieder wie ein Zauber.
quelle