2010-01-22 14 views
6

Stiamo utilizzando SQL Server 2005 con Reporting Services.Prestazioni lente di Reporting Services, molto veloce in QueryAnalyser

Abbiamo un numero di report, ciascuno contenente una query SQL relativamente semplice: per "relativamente" intendo che abbiamo alcuni join, ma niente di peggio. Non chiamiamo alcuna stored procedure nelle nostre query - questo non è il caso dello sniffing dei parametri.

Quando si esegue uno di questi report (chiamiamolo report A) tramite Reporting Services, ci vuole molto tempo per completare - nell'ordine di decine di minuti o addirittura di ore. Quando si esegue la query SQL corrispondente in Query Analyzer, viene completata in pochi secondi.

Il numero di righe restituite dal database può essere pari a 1 - tuttavia, il report non viene mai completato.

Gli altri report funzionano correttamente.

Guardando nella tabella ExecutionLog su Reporting Services, posso vedere che la maggior parte del tempo è in TimeDataRetrieval (e stiamo parlando di milioni di secondi qui ...) - le volte in cui il report viene effettivamente completato. Se il report viene interrotto manualmente, TimeDataRetrieveal è zero e TimeProcessing è invece assurdamente alto.

Ho esaminato i registri di Reporting Services, ma tutto sembra normale.

Ora, prima di iniziare a suggerire "blocco" - beh, le nostre query hanno il suggerimento nolock attivato.

Allo stato attuale, ho raggiunto il limite della mia immaginazione cercando di trovare l'errore. Qualsiasi pensiero, intuizione sarebbe gradita.

/Christoffer

+0

Provare a utilizzare SQL profiler per vedere come la stessa query viene ricevuta in modo diverso quando viene passata da Query Analyzer a Reporting Services e vedere quanto tempo impiega ciascuno di essi per terminarlo. Potrebbe essere l'interpretazione dei parametri che potrebbe causare problemi a Reporting Services? – shahkalpesh

+0

Grazie per il tuo commento. Ho provato a utilizzare SQL Profiler. I parametri sono abbastanza semplici: due date e alcune stringhe. Le date sarebbero i primi sospettati, ma sembrano interpretati ok. Nulla spicca nel profiler, i parametri inviati a SetSessionParameters sembrano ok. – Christoffer

+0

Devo anche aggiungere che posso eseguire il report direttamente in Visual Studio senza problemi. – Christoffer

risposta

5

Ho finito per spogliare la query, fondamentalmente una dichiarazione alla volta, fino a quando ho trovato il colpevole. Uno dei join nella query è entrato in una tabella in continua crescita (milioni di righe), usando un suggerimento "con (nolock index (x))".

La rimozione del suggerimento indice in Query Analyzer mi ha dato lo stesso risultato di Reporting Services - una query lenta molto . Questo non è sorprendente di per sé - ma in effetti sembrava che la query su RS non usasse il suggerimento.

Ho quindi provato a eseguire nuovamente il rapporto in RS utilizzando l'istruzione SET FORCEPLAN ON. E ... ha funzionato: il tempo di esecuzione è ora di alcuni secondi, come dovrebbe essere.A quanto ho capito, l'opzione FORCEPLAN forza SQL Server a elaborare i join nell'ordine indicato, E a prendere in considerazione qualsiasi suggerimento.

Qualcuno ha qualche idea sul motivo per cui la query tramite RS ignorerebbe il suggerimento, quando ovviamente Query Analyzer lo tiene in considerazione?

2

Durante l'esecuzione del rapporto, provare co piano di esecuzione cattura utilizzando SQL Profiler. Dai un'occhiata se non hai operatori CONVER_IMPLICIT per esempio e scansioni tabella/indice in generale.

http://msdn.microsoft.com/en-us/library/ms190233.aspx

Le conversioni impediscono indici vengano utilizzati e può accadere se si passa parametri che hanno tipo diverso dalle colonne li confronta.

Si potrebbe provare ad aggiungere OPTION (RECOMPILE) alla query del report, è possibile che il report sia vittima di parameter sniffing.

Verificare se le query utilizzano funzioni scalari definite dall'utente. Possono essere veri assassini di prestazioni. Se li hai, potrebbe essere possibile convertirli in table valued functions.

+0

Grazie per la risposta. Ho trovato la risposta da solo ieri, vedi sotto. – Christoffer

0

Un aggiornamento rapido: sembrerebbe che qualsiasi query che richiede più di 30 secondi per l'esecuzione, causerà automaticamente un timeout in Reporting Services. Mentre SET FORCEPLAN ON risolveva i problemi relativi ad alcuni report, c'erano ancora segnalazioni di problemi che avrebbero interrotto il timeout. Queste query funzionavano ancora correttamente in Query Analyzer, sebbene il tempo di esecuzione fosse superiore a 30 secondi. Dopo aver eliminato tutti gli altri possibili problemi con le impostazioni di timeout - sul server SQL, in Reporting Services, rsserver.config, in IIS - ho scoperto che c'era ancora un timeout che non potevo modificare.

Il mio sospetto è che abbia a che fare con il timeout predefinito di ADO.NET e che Microsoft non ci abbia lasciato alcun modo di modificare questo valore.

Infine, ho finito per dare un'occhiata più approfondita alla query, riorganizzandola al meglio delle mie possibilità e riuscendo a strappare alcuni secondi dal tempo di esecuzione. Ora, finalmente, i rapporti stanno funzionando come dovrebbero.

Questo timeout non modificabile mi preoccupa, tuttavia, cosa succederà se il server SQL ha un carico più elevato del normale quando viene eseguita la query?

2

Ho affrontato la stessa situazione.

In Management Studio i risultati sono arrivati ​​dopo venti secondi ma quando eseguo il report in Visual Studio ha bloccato il sistema.

in SQL Profiler ho tracciato la query e si rese conto che trasforma la mia domanda come:

exec sp_executesql N' 
       .................... 
       ....................' 
, @dateparameter1 = '2010-06-01 00:00:00' 
, @datepamareter2 = '2010-06-02 00:00:00' 
, @stringparameter=null 

Ho esaminato il piano di esecuzione e si rese conto che ero una vittima del parametro sniffing.

Ho riorganizzato la mia domanda come è stato detto here, e funziona bene ora ..

1

E 'successo anche a me, è stato il parametro sniffing. Stavo usando la stessa vista del report da usare come filtro, usando solo i campi che volevo.

Quello che ho fatto è stato creare una vista per il filtro ed è stato risolto.

Problemi correlati