Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Macht SET NOCOUNT ON wirklich einen so großen Leistungsunterschied

Es gibt Szenarien, in denen SET NOCOUNT ON obligatorisch ist. Beim Entwerfen einer hochleistungsfähigen Mid-Tier basierend auf asynchroner Verarbeitung, die den Thread-Pool über die BeginExecuteXXX-Methoden von SqlClient nutzt, gibt es ein sehr ernstes Problem mit der Zeilenanzahl. Die BeginExecute-Methoden werden abgeschlossen, sobald die erste Antwortpaket wird vom Server zurückgesendet. Wenn jedoch ein EndExecuteXXX aufgerufen wird, wird dies bei Nicht-Abfrageanforderungen abgeschlossen, wenn der Aufruf abgeschlossen ist. Jede Rowcount-Antwort ist eine Antwort. Bei der Verarbeitung selbst mäßig komplexer Prozeduren könnte die erste Zeilenzählung in 5-10 ms zurückkommen, während der Aufruf in 300-500 ms abgeschlossen ist. Anstatt die gesendete asynchrone Anforderung nach 500 ms zurückrufen zu lassen, ruft sie nach 5 ms zurück und dann blockiert der Rückruf in EndExecuteXXX für 495 ms. Das Ergebnis ist, dass asynchrone Aufrufe vorzeitig abgeschlossen werden und einen Thread aus dem Threadpool in den EndExecuteNonQuery-Aufrufen blockieren. Dies führt zu ThreadPool-Hunger. Ich habe gesehen, dass Hochleistungssysteme den Durchsatz von Hunderten von Aufrufen pro Sekunde auf Tausende von Aufrufen pro Sekunde verbessern, indem in bestimmten Szenarien einfach SET NOCOUNT ON hinzugefügt wird.

Angesichts der Tatsache, dass asynchrone Aufrufe für die Midle-Tier-Verarbeitung mit hohem Umfang und hohem Durchsatz der einzige Weg sind, ist NOCOUNT so ziemlich eine obligatorische Anforderung.