Domanda

Questa è una domanda che ho posto su un altro forum che ha ricevuto alcune risposte decenti, ma volevo vedere se qualcuno qui ha maggiori informazioni.

Il problema è che una delle tue pagine in un'applicazione Web scade quando arriva a una chiamata di procedura memorizzata, quindi usi Sql Profiler o i registri di traccia dell'applicazione per trovare la query e la incolli in Management Studio per capire il nostro motivo per cui funziona lentamente.Ma lo esegui da lì e divampa, ritornando ogni volta in meno di un secondo.

Il mio caso particolare utilizzava ASP.NET 2.0 e Sql Server 2005, ma penso che il problema potrebbe applicarsi a qualsiasi sistema RDBMS.

È stato utile?

Soluzione

Questo è ciò che ho imparato finora dalla mia ricerca.

.NET invia impostazioni di connessione che non sono le stesse che ottieni quando accedi a Management Studio.Ecco cosa vedi se annusi la connessione con Sql Profiler:

-- 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  

Ora incollo queste impostazioni sopra ogni query che eseguo quando accedo al server SQL, per assicurarmi che le impostazioni siano le stesse.

In questo caso, ho provato ciascuna impostazione individualmente, dopo essermi disconnesso e ricollegato, e ho scoperto che la modifica di arithabort da disattivato a attivato riduceva la query del problema da 90 secondi a 1 secondo.

La spiegazione più probabile è legata allo sniffing dei parametri, che è una tecnica utilizzata da SQL Server per scegliere quello che ritiene sia il piano di query più efficace.Quando modifichi una delle impostazioni di connessione, Query Optimizer potrebbe scegliere un piano diverso e, in questo caso, apparentemente ne ha scelto uno sbagliato.

Ma di questo non ne sono del tutto convinto.Ho provato a confrontare i piani di query effettivi dopo aver modificato questa impostazione e non ho ancora visto le differenze mostrare eventuali modifiche.

C'è qualcos'altro nell'impostazione arithabort che in alcuni casi potrebbe rallentare l'esecuzione di una query?

La soluzione sembrava semplice:Basta inserire set arithabort nella parte superiore della procedura memorizzata.Ma questo potrebbe portare al problema opposto:modifica i parametri della query e improvvisamente funziona più velocemente con "off" che con "on".

Per il momento sto eseguendo la procedura 'con ricompilazione' per assicurarmi che il piano venga rigenerato ogni volta.Va bene per questo particolare report, poiché ci vuole forse un secondo per ricompilare, e questo non è troppo evidente su un report che impiega 1-10 secondi per tornare (è un mostro).

Ma non è un'opzione per altre query che vengono eseguite molto più frequentemente e devono essere restituite il più rapidamente possibile, in pochi millisecondi.

Altri suggerimenti

Ho avuto problemi simili.Prova a impostare l'opzione with "WITH RECOMPILE" su sproc create per forzare il sistema a ricalcolare il piano di esecuzione ogni volta che viene chiamato.A volte il Query Processor si confonde in procedure memorizzate complesse con molte ramificazioni o istruzioni case e genera semplicemente un piano di esecuzione davvero non ottimale.Se questo sembra "risolvere" il problema, probabilmente dovrai verificare che le statistiche siano aggiornate e/o scomporre lo sproc.

Puoi anche confermarlo profilando lo sproc.Quando lo esegui da SQL Management Studio, come si confronta l'IO con quando lo profili dall'applicazione ASP.NET.Se sono moltissimi, rafforza semplicemente il fatto che si sta elaborando un cattivo piano di esecuzione.

Hai già attivato la traccia ASP.NET?Ho avuto un'istanza in cui il problema non era la procedura memorizzata SQL stessa, ma il fatto che la procedura restituiva 5000 righe e l'app stava tentando di creare ListItem associati a dati con quei 5000 elementi a causare il problema.

Potresti esaminare i tempi di esecuzione tra le funzioni dell'app Web anche attraverso la traccia per tenere traccia delle cose.

provalo prima su una scatola di staging, modificalo a livello di server per SQL Server

dichiarare @opzione int

Set @option = @@ opzioni | 64

Exec SP_Configure "Opzioni utente", @Option

RICONFIGURARE

Stesso problema che ho avuto con i servizi di reporting SQL.Prova a controllare il tipo di variabili, stavo inviando un diverso tipo di variabile a SQL come inviare Varchar in atto dove dovrebbe essere intero o qualcosa del genere.Dopo aver sincronizzato i tipi di variabili in Reporting Service e nella procedura memorizzata su SQL, ho risolto il problema.

Potresti provare a utilizzare il comando sp_who2 per vedere quale processo sta facendo.Questo ti mostrerà se è bloccato da un altro processo o se utilizza una quantità eccessiva di CPU e/o tempo io.

Abbiamo avuto lo stesso problema ed ecco cosa abbiamo scoperto.

la dimensione del registro del nostro database veniva mantenuta al valore predefinito (814 MB) e la crescita automatica era del 10%.Sul server, anche la memoria massima del server è stata mantenuta all'impostazione predefinita (2147483647 MB).

Quando il nostro registro si è riempito e aveva bisogno di crescere, ha utilizzato tutta la memoria del server e non è rimasto più nulla per l'esecuzione del codice, quindi è scaduto.Ciò che abbiamo fatto è stato impostare la dimensione iniziale del file di registro del database su 1 MB e la memoria massima del server su 2048 MB.Questo ha risolto immediatamente il nostro problema.Naturalmente, puoi modificare queste due proprietà in base alle tue esigenze, ma questa è un'idea per qualcuno che si imbatte in un problema di timeout durante l'esecuzione di una procedura memorizzata tramite codice, ma funziona molto velocemente in SSMS e le soluzioni di cui sopra non aiutano.

Prova a modificare il valore di timeout di SelectCommand:

DataAdapter.SelectCommand.CommandTimeout = 120;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top