Frage

Ich versuche, die Quelle eines SQL-Timeout in einer Web-Anwendung zu debuggen, dass ich halten. Ich habe den Quellcode des Codes hinter C #, damit ich weiß genau, welcher Code ausgeführt wird. Ich habe die Anwendung bis auf die Linie debuggt, die den SQL-Code, dass die Zeiten heraus ausgeführt wird, und ich sehe die Abfrage in SQL Profiler ausgeführt wird.

Wenn diese Abfrage ausgeführt wird aus dem Internet, es mal nach 30 Sekunden. Allerdings, wenn ich Ausschneiden / Einfügen die Abfrage genau wie in Profiler dargestellt, und ich habe es in SSMS und führen Sie es, es fast sofort zurückgibt. Ich habe das Problem zu ARITHABORT ist auf OFF in der Verbindung zurückgeführt, dass die Bahn mit (das heißt, wenn ich ARITHABORT OFF in der SSMS-Sitzung starten, wird es für eine lange Zeit, und wenn ich es wieder einzuschalten, dann läuft es sehr schnell). Um jedoch die Beschreibung des ARITHABORT lesen, es scheint nicht zu gelten ... Ich bin nur eine einfache SELECT zu tun, und es gibt keine arithmetischen Wesen überhaupt durchgeführt .. nur ein einzige INNER JOIN mit WHERE-Bedingung:

Warum wäre ARITHABORT OFF dieses Verhalten in diesem Zusammenhang verursacht ?? Gibt es eine Möglichkeit, die ARITHABORT Einstellung für die Verbindung von SSMS verändern kann? Ich bin mit SQL Server 2008.

War es hilfreich?

Lösung

So C # -Code eine Ad-hoc-SQL-Abfrage an SQL Server sendet, mit welcher Methode? Haben Sie eine gespeicherte Prozedur als mit? Das wäre wahrscheinlich die gleiche Leistung (zumindest im Motor), unabhängig davon sicherzustellen, die es genannt.

Warum? Die ARITHABORT Einstellung ist eines der Dinge, die Optimierer betrachtet, wenn es zu bestimmen, wie Sie Ihre Anfrage auszuführen (genauer gesagt für die Plananpassung). Es ist möglich, dass der Plan im Cache die gleiche Einstellung wie SSMS hat, so dass er die im Cache gespeicherten Plan verwendet, aber mit dem anderen ist C # -Code Einstellen eines recompile zwingen (oder vielleicht schlagen Sie ein wirklich BAD Plan im Cache), die sicherlich die Leistung in vielen Fällen verletzen können.

Wenn Sie bereits eine gespeicherte Prozedur aufrufen (Sie nicht Ihre Abfrage veröffentlichen, obwohl ich glaube, du gemeint), können Sie versuchen OPTION Hinzufügen (RECOMPILE) an die säumige Abfrage (oder Abfragen) in der gespeicherten Prozedur. Das bedeutet, diese Aussagen immer neu kompilieren, aber es könnte die Verwendung des schlechten Plan, den Sie zu schlagen scheinen zu verhindern. Eine weitere Option ist, um sicherzustellen, dass, wenn die gespeicherte Prozedur kompiliert wird, wird der Ansatz mit SET ARITHABORT ON ausgeführt.

Schließlich scheinen Sie zu fragen, wie Sie die ARITHABORT Einstellung in SSMS ändern können. Ich denke, was Sie zu fragen, gemeint ist, wie Sie die ARITHABORT Einstellung in Ihrem Code zu erzwingen. Wenn Sie sich entscheiden App weiterhin zu senden Ad-hoc-SQL von C #, dann natürlich können Sie einen Befehl als Text senden, die durch Semikolons mehr Anweisungen getrennt hat, z.

SET ARITHABORT ON; SELECT ...

Für weitere Informationen darüber, warum dieses Problem auftritt, sieht Erland Sommarskog des großen Artikel:

Andere Tipps

Diese Antwort enthält eine Möglichkeit, dieses Problem zu beheben:

  

Durch die folgenden Befehle als Administrator ausgeführt wird auf der Datenbank alle Abfragen unabhängig von der Einstellung ARITHABORT wie erwartet ausgeführt.

 DBCC DROPCLEANBUFFERS
 DBCC FREEPROCCACHE

Update

Es scheint, dass die meisten Menschen dieses Problem sehr selten auftreten, am Ende mit, und die oben beschriebene Technik ist eine anständige einmalige Lösung. Aber wenn eine bestimmte Abfrage dieses Problem mehr als einmal zeigt, eine langfristige Lösung für dieses Problem wäre Abfrage Hinweise wie OPTIMIZE FOR und OPTION(Recompile) zu verwenden, wie in dieser Artikel .

Ich habe dieses Problem oft habe vor, aber wenn Sie eine gespeicherte Prozedur mit dem gleichen Problem Abwurf und die gespeicherte Prozedur neu erstellt werden, das Problem lösen.

Es heißt Parameter Sniffing. Sie müssen immer die Parameter in der gespeicherten proc lokalisieren dieses Problem in Zukunft zu vermeiden.

Ich verstehe das vielleicht nicht, was das ursprüngliche Plakat will aber helfen könnte jemand mit dem gleichen Problem.

Wenn Entity Framework verwenden Sie müssen sich bewusst sein, dass Abfrageparameter für String-Werte werden in die Datenbank als nvarchar standardmäßig gesendet, wenn Datenbankspalte vergleichen varchar eingegeben wird, je nach Sortierung, Abfrageausführungsplan kann eine „implizite Umwandlung“ erfordert Schritt, dass die Kräfte ein Scan. Ich konnte es von der Suche in der Datenbank bestätige in teueren Abfragen Option Überwachung, die zeigt den Ausführungsplan.

Schließlich ist eine Erklärung zu diesem Verhalten in diesem Beitrag: https://www.sqlskills.com/blogs / jonathan / implizite-Conversions-that-Ursache-Index-Scans /

Ich hatte das gleiche Problem, und es wurde durch Ausführen von Verfahren „WITH RECOMPILE“ festgelegt. Sie können auch versuchen Parameter Schnüffeln verwenden. Mein Problem wurde in SQL-Cache verwendet.

Wenn Sie Ihren Code fix ändern optimize für unbekannten Hinweis Parameter Sniffing ist die beste Option. Wenn Sie Ihren Code nicht die beste Option, ändern kann, ist exec sp_recompile ‚Namen proc‘, die nur das eine gespeicherte Prozedur zwingen wird, einen neuen Ausführungsplan zu erhalten. Dropping und ein proc Neuer würde eine ähnliche Wirkung haben, aber könnte zu Fehlern führen, wenn jemand die proc auszuführen versucht, während Sie sie fallen gelassen haben. DBCC FREEPROCCACHE löscht alle zwischengespeicherten Pläne, die Chaos in Ordnung, das System bis zu und verursacht viele Timeouts in einem schweren Transaktionen Produktionsumgebung einschließlich Wrack. arithabort Einstellung ist keine Lösung für das Problem, sondern ist ein nützliches Werkzeug für die Entdeckung, wenn der Parameter Sniffing das Problem ist.

Ich habe das gleiche Problem, wenn sie versuchen SP von SMSS zu nennen es 2 Sekunden dauerte, während sie von der Webapp (ASP.NET) es ca. 3 min dauerte.

Ich habe versucht, alle vorgeschlagenen Lösungen sp_recompile, DBCC FREEPROCCACHE und DBCC DROPCLEANBUFFERS aber nichts fixiert mein Problem, aber wenn versucht Parameter Sniffing es der Trick, und funktionierte gut.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top