Domanda

Sto cercando di eseguire il debug dell'origine di un timeout SQL in un'applicazione Web che mantengo.Ho il codice sorgente del codice C# dietro, quindi so esattamente quale codice è in esecuzione.Ho eseguito il debug dell'applicazione fino alla riga che esegue il codice SQL che scade e guardo la query in esecuzione nel profiler SQL.

Quando questa query viene eseguita dal Web, scade dopo 30 secondi.Tuttavia, quando taglio/incollo la query esattamente come presentata in Profiler, la inserisco in SSMS e la eseguo, ritorna quasi istantaneamente.Ho rintracciato il problema nel fatto che ARITHABORT è impostato su OFF nella connessione utilizzata dal Web (ovvero, se disattivo ARITHABORT nella sessione SSMS, funziona a lungo e se lo riaccendo, viene eseguito molto velocemente).Tuttavia, leggendo la descrizione di ARITHABORT, non sembra applicarsi...Sto solo eseguendo una semplice SELEZIONE e NON viene eseguita alcuna operazione aritmetica.solo un singolo INNER JOIN con una condizione WHERE:

Perché ARITHABORT OFF dovrebbe causare questo comportamento in questo contesto??Esiste un modo per modificare l'impostazione ARITHABORT per quella connessione da SSMS?Sto utilizzando SQL Server 2008.

È stato utile?

Soluzione

Così il vostro codice C # è l'invio di una query ad hoc SQL per SQL Server, utilizzando quale metodo? Hai pensato di usare una stored procedure? Che probabilmente garantire le stesse prestazioni (almeno nel motore) indipendentemente da chi ha chiamato.

Perché? L'impostazione ARITHABORT è una delle cose che l'ottimizzatore esamina quando è determinare come eseguire la query (più specificamente, per la corrispondenza plan). E 'possibile che il piano nella cache ha la stessa impostazione come SSMS, in modo che utilizza il piano memorizzato nella cache, ma con l'opposto impostare il codice C # sta costringendo una ricompilazione (o forse si stanno colpendo davvero BAD piano nella cache), che può certamente influire negativamente sulle prestazioni in molti casi.

Se sei già chiamando una stored procedure (non hai postare la tua ricerca, anche se penso che si intende a), si può provare ad aggiungere OPTION (RECOMPILE) per la query incriminato (o query) nella stored procedure. Questo significherà tali dichiarazioni saranno sempre ricompilare, ma potrebbe impedire l'uso del cattivo piano che sembra di essere colpito. Un'altra opzione è quella di fare in modo che quando la stored procedure viene compilato, il batch viene eseguito con SET ARITHABORT ON.

Infine, ti sembra di essere chiedendo come è possibile modificare l'impostazione ARITHABORT in SSMS. Credo che ciò che si intende chiedere è come si può forzare l'impostazione ARITHABORT nel codice. Se si decide di continuare l'invio di SQL ad hoc dal C # app, poi, naturalmente, è possibile inviare un comando come testo che ha più istruzioni separati da punti e virgola, per esempio:.

SET ARITHABORT ON; SELECT ...

Per ulteriori informazioni sul motivo per cui si verifica questo problema, vedere l'articolo di grande Erland Sommarskog:

Altri suggerimenti

Questa risposta include un modo per risolvere questo problema:

Eseguendo i seguenti comandi come amministratore sul database, tutte le query verranno eseguite come previsto indipendentemente dall'impostazione ARITHABORT.

 DBCC DROPCLEANBUFFERS
 DBCC FREEPROCCACHE

Aggiornamento

Sembra che la maggior parte delle persone finisca per riscontrare che questo problema si verifichi molto raramente e la tecnica di cui sopra è una soluzione decente una tantum.Ma se una query specifica presenta questo problema più di una volta, una soluzione a lungo termine a questo problema sarebbe quella di utilizzare suggerimenti per la query come OPTIMIZE FOR E OPTION(Recompile), come descritto in Questo articolo.

Ho avuto questo problema molte volte prima, ma se si dispone di una stored procedure con lo stesso problema lasciando cadere e ricreare la stored procedure risolverà il problema.

Si chiama parametro sniffing. È necessario localizzare sempre i parametri nella stored procedure per evitare questo problema in futuro.

Capisco questo potrebbe non essere quello che il manifesto originale vuole, ma potrebbe aiutare qualcuno con lo stesso problema.

Se si utilizza Entity Framework è necessario essere consapevoli del fatto che i parametri di query per valori di stringa vengono inviati al database come nvarchar per difetto, se la colonna del database per confrontare viene digitato varchar, a seconda della raccolta, interrogare piano di esecuzione può richiedere una "conversione implicita" passo, che forza una scansione completa. Ho potuto confermarlo, cercando nel monitoraggio database in opzione query costosa, che visualizza il piano di esecuzione.

Infine, una spiegazione su questo comportamento in questo articolo: https://www.sqlskills.com/blogs / / Jonathan impliciti conversioni-che-causa-index-scan /

Ho avuto lo stesso problema ed è stato risolto eseguendo procedura "WITH RECOMPILE". Si può anche provare a utilizzare il parametro sniffing. Il mio problema era legato alla cache SQL.

Se è possibile modificare il codice per risolvere parametro sniffing ottimizzare per sconosciuto suggerimento è la soluzione migliore. Se non è possibile modificare il codice l'opzione migliore è exec sp_recompile 'nome proc' che costringerà solo quella stored procedure per ottenere un nuovo piano di esecuzione. Lasciando cadere e ricreare un proc avrebbe un effetto simile, ma potrebbe causare errori se qualcuno tenta di eseguire il proc mentre si ha è sceso. DBCC FREEPROCCACHE gocce tutti i vostri piani memorizzati nella cache che possono rovinare il caos ok il sistema fino al causando un sacco di timeout in un ambiente di produzione transazioni pesante. L'impostazione ARITHABORT non è una soluzione al problema, ma è uno strumento utile per scoprire se il parametro sniffing è il problema.

Ho lo stesso problema quando si cerca di chiamare SP da SMSS ci sono voluti 2 sec, mentre dalla webapp (ASP.NET) ci sono voluti circa 3 minuti.

Ho provato tutte le soluzioni suggerite sp_recompile, DBCC FREEPROCCACHE e DBCC DROPCLEANBUFFERS ma niente risolto il mio problema, ma quando cercai parametro sniffing è andato benone, e ha lavorato bene.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top