Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

SET NOCOUNT ON fa davvero tanta differenza in termini di prestazioni

Ci sono scenari in cui SET NOCOUNT ON è obbligatorio. Quando si progetta un livello intermedio ad alte prestazioni basato sull'elaborazione asincrona che sfrutta il pool di thread tramite i metodi BeginExecuteXXX di SqlClient, esiste un problema molto serio con il conteggio delle righe. I metodi BeginExecute vengono completati non appena il primo il pacchetto di risposta viene restituito dal server. Ma quando viene richiamato un EndExecuteXXX, questo viene completato su richieste non di query quando la chiamata è completa. Ogni risposta al conteggio delle righe è una risposta. Quando si elaborano procedure anche moderatamente complesse, il conteggio della prima riga potrebbe tornare in 5-10 ms, mentre la chiamata si completa in 300-500 ms. Invece di richiamare la richiesta asincrona inviata dopo 500 ms, richiama dopo 5 ms e quindi la richiamata si blocca in EndExecuteXXX per 495 ms. Il risultato è che le chiamate asincrone vengono completate prematuramente e bloccano un thread dal pool di thread nelle chiamate EndExecuteNonQuery. Questo porta alla fame di ThreadPool. Ho visto sistemi ad alte prestazioni migliorare il throughput da centinaia di chiamate al secondo a migliaia di chiamate al secondo semplicemente aggiungendo il SET NOCOUNT ON, su scenari specifici.

Dato che le chiamate asincrone per l'elaborazione di livello medio/alto throughput sono l'unica strada da percorrere, il NOCOUNT è praticamente un requisito obbligatorio.