2008-08-13 8 views
27

Questa è una domanda che ho posto su un altro forum che ha ricevuto alcune risposte decenti, ma volevo vedere se qualcuno qui ha più informazioni.La query è scaduta dall'app Web ma funziona correttamente dallo studio di gestione

Il problema è che si ha una delle pagine in un'applicazione Web che si interrompe quando arriva a una chiamata di stored procedure, quindi si utilizza Sql Profiler oi log di traccia delle applicazioni per trovare la query e la si incolla in studio di gestione per capire perché è lento. Ma tu lo esegui da lì e tutto scorre a vuoto, ritornando in meno di un secondo ogni volta.

Il mio caso particolare era l'utilizzo di ASP.NET 2.0 e Sql Server 2005, ma penso che il problema potrebbe riguardare qualsiasi sistema RDBMS.

+0

Ho avuto lo stesso problema e http://stackoverflow.com/questions/250713/sqldataadapter-fill-method-slow ha risolto il mio problema – David

risposta

26

Questo è quello che ho imparato finora dalla mia ricerca.

.NET invia le impostazioni di connessione che non corrispondono a quelle ottenute quando si accede allo studio di gestione. Ecco ciò che si vede se si annusa il collegamento 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 sto incollando quelli impostazione di sopra di ogni query che ho eseguito quando si accede al server SQL, per assicurarsi che le impostazioni sono le stesse.

In questo caso, ho provato ciascuna impostazione singolarmente, dopo aver scollegato e ricollegato, e ho scoperto che la modifica di arithabort da off a on ha ridotto la query del problema da 90 secondi a 1 secondo.

La spiegazione più probabile è relativa allo sniffing dei parametri, che è una tecnica utilizzata da Sql Server per selezionare quello che ritiene sia il piano di query più efficace. Quando si modifica una delle impostazioni di connessione, Query Optimizer potrebbe scegliere un piano diverso e in questo caso, apparentemente, ha scelto un programma non valido.

Ma non ne sono totalmente convinto. Ho provato a confrontare i piani di query effettivi dopo aver modificato questa impostazione e devo ancora vedere la differenza mostrare eventuali modifiche.

C'è qualcos'altro nell'impostazione di arithabort che potrebbe causare una query in modo lento in alcuni casi?

La soluzione sembrava semplice: basta mettere arithabort su nella parte superiore della stored procedure. Ma questo potrebbe portare al problema opposto: cambiare i parametri della query e improvvisamente funziona più velocemente con 'off' rispetto a 'on'.

Per ora sto eseguendo la procedura 'con ricompilare' 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 in un report che richiede da 1 a 10 secondi per tornare (è un mostro).

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

+1

+1 Afferrare queste impostazioni da SQL Profiler e incollarle in Management Studio è un ottimo consiglio e mi ha aiutato a caricare. –

+3

+1 SET ARITHABORT OFF è stato sufficiente per far funzionare correttamente la query di time-out precedente. – Spud

+1

@ eric-z-beard Dove metti questi valori? All'interno dell'SP o prima di EXEC sp_whatever da .NET – djandreski

0

provare a cambiare il valore di timeout SelectCommand:

DataAdapter.SelectCommand.CommandTimeout = 120; 
+0

Non è una soluzione! È un trucco! – Icet

1

testare il tutto su una scatola messa in scena prima, cambiare su un livello di server per il server SQL

dichiarare @option int

set @option = @@ opzioni | 64

exec sp_configure 'opzioni utente', @option

riconfigurare

2

Avete acceso ASP.NET tracciamento ancora? Ho avuto un'istanza in cui non era la stessa procedura memorizzata SQL a rappresentare il problema, era il fatto che la procedura restituiva 5000 righe e l'app stava tentando di creare listItem in databound con quei 5000 elementi che causavano il problema.

È possibile esaminare i tempi di esecuzione tra le funzioni dell'applicazione Web e la traccia per aiutare a rintracciare le cose.

0

Si potrebbe provare a utilizzare il comando sp_who2 per vedere quale processo in questione sta facendo. Questo ti mostrerà se è bloccato da un altro processo, o usando una quantità eccessiva di CPU e/o tempo.

1

Lo stesso problema riscontrato con i servizi di report SQL. Prova a controllare il tipo di variabili, Stavo inviando un diverso tipo di variabile a SQL come l'invio di varchar in posizione dove dovrebbe essere essere intero, o qualcosa del genere. Dopo aver sincronizzato i tipi di variabili in Reporting Service e in stored procedure su SQL, ho risolto il problema.

6

Ho avuto problemi simili. Prova a impostare l'opzione "WITH RECOMPILE" su sproc create per forzare il sistema a ricalcolare il piano di esecuzione ogni volta che viene chiamato. A volte il processore Query viene confuso in complesse procedure memorizzate con un sacco di istruzioni di branching o case e semplicemente tira un piano di esecuzione davvero sub-ottimale. Se questo sembra "aggiustare" il problema, probabilmente avrai bisogno di verificare che le statistiche siano aggiornate e/o abbattere lo sproc.

È inoltre possibile confermare questo profilando il sproc. Quando lo esegui da SQL Managment Studio, come si confronta l'IO quando lo si profila dall'applicazione ASP.NET. Se molto, si limita a rafforzare il suo piano di esecuzione errato.

0

Abbiamo avuto lo stesso problema ed ecco cosa abbiamo scoperto.

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

Quando il nostro registro si riempiva e aveva bisogno di crescere, utilizzava tutta la memoria dal server e non è rimasto nulla per il codice da eseguire, quindi è scaduto. Quello che abbiamo finito è stato impostare la dimensione iniziale del file di registro del database su 1 MB e la memoria del server massima su 2048 MB. Questo ha risolto istantaneamente il nostro problema. Naturalmente, è possibile modificare queste due proprietà in base alle proprie esigenze, ma questa è un'idea per qualcuno che si imbatte nel problema di temporizzazione durante l'esecuzione di una procedura memorizzata tramite codice ma funziona in modo super veloce in SSMS e le soluzioni di cui sopra non aiutano.

Problemi correlati