Das habe ich bisher aus meiner Forschung gelernt.
.NET sendet Verbindungseinstellungen, die nicht mit denen übereinstimmen, die Sie erhalten, wenn Sie sich bei Management Studio anmelden. Folgendes sehen Sie, wenn Sie die Verbindung mit Sql Profiler ausspionieren:
-- network protocol: TCP/IP
set quoted_identifier off
set arithabort off
set numeric_roundabort off
set ansi_warnings on
set ansi_padding on
set ansi_nulls off
set concat_null_yields_null on
set cursor_close_on_commit off
set implicit_transactions off
set language us_english
set dateformat mdy
set datefirst 7
set transaction isolation level read committed
Ich füge diese Einstellung jetzt über jeder Abfrage ein, die ich ausführe, wenn ich beim SQL-Server angemeldet bin, um sicherzustellen, dass die Einstellungen gleich sind.
Für diesen Fall habe ich jede Einstellung einzeln ausprobiert, nachdem ich die Verbindung getrennt und wieder hergestellt hatte, und festgestellt, dass das Ändern von arithabort von Aus auf Ein die Problemabfrage von 90 Sekunden auf 1 Sekunde reduzierte.
Die wahrscheinlichste Erklärung bezieht sich auf das Parameter-Sniffing, eine Technik, die Sql Server verwendet, um den seiner Meinung nach effektivsten Abfrageplan auszuwählen. Wenn Sie eine der Verbindungseinstellungen ändern, wählt der Abfrageoptimierer möglicherweise einen anderen Plan, und in diesem Fall hat er anscheinend einen schlechten gewählt.
Davon bin ich aber nicht ganz überzeugt. Ich habe versucht, die tatsächlichen Abfragepläne zu vergleichen, nachdem ich diese Einstellung geändert habe, und ich muss noch sehen, dass der Diff irgendwelche Änderungen zeigt.
Gibt es etwas anderes an der arithabort-Einstellung, das dazu führen kann, dass eine Abfrage in einigen Fällen langsam ausgeführt wird?
Die Lösung schien einfach:Setzen Sie einfach set arithabort oben in die gespeicherte Prozedur. Dies könnte aber zum gegenteiligen Problem führen:Ändern Sie die Abfrageparameter und plötzlich läuft es mit 'off' schneller als mit 'on'.
Im Moment führe ich die Prozedur "mit Neukompilierung" aus, um sicherzustellen, dass der Plan jedes Mal neu generiert wird. Für diesen speziellen Bericht ist es in Ordnung, da die Neukompilierung vielleicht eine Sekunde dauert, und dies fällt bei einem Bericht, der 1-10 Sekunden braucht, um zurückzukehren, nicht zu stark auf (es ist ein Monster).
Aber es ist keine Option für andere Abfragen, die viel häufiger ausgeführt werden und so schnell wie möglich, in nur wenigen Millisekunden, zurückkehren müssen.