Perché un report SSRS scade quando la Stored procedure si basa sui risultati di restituzione entro pochi secondi?

StackOverflow https://stackoverflow.com/questions/237069

Domanda

Ho un rapporto che visualizza i dati restituiti da una procedura memorizzata. Utilizzando il profiler posso ricevere la chiamata alla procedura memorizzata dai servizi di segnalazione.

Il rapporto non riesce a dichiarare scaduto il rapporto, ma posso eseguire la procedura memorizzata da SSMS e restituisce i dati in 5-6 secondi.

Nota, nell'esecuzione del test di esempio solo due righe vengono restituite al report per il rendering sebbene all'interno della procedura memorizzata potrebbe aver funzionato su migliaia o addirittura milioni di record al fine di raccogliere il risultato restituito ai servizi di reporting.

So che la procedura memorizzata potrebbe essere ottimizzata di più, ma non capisco perché SSRS sarebbe scaduto quando l'esecuzione sembra richiedere solo pochi secondi per essere eseguita da SSMS.

È emerso anche un altro problema. Se ricreare la procedura memorizzata, il report inizia nuovamente a essere perfettamente funzionante. Va bene, tranne dopo un breve periodo di tempo, il rapporto inizia di nuovo a scadere.

Il ritorno del timeout sembra essere correlato ai nuovi dati aggiunti nella tabella principale contro cui è in esecuzione il report. Nell'esempio che stavo testando, sono stati inseriti solo cento nuovi record per rovinare il rapporto.

Immagino più correttamente che non sia il rapporto che è la causa principale. È la procedura memorizzata che causa il timeout quando eseguita da SSRS.

Una volta scaduto il timeout, la soluzione migliore che ho finora è ricreare la procedura memorizzata. Questa non sembra essere una soluzione ideale.

Il problema sembra verificarsi anche nel nostro ambiente di produzione. Le nostre piattaforme di test e sviluppo non sembrano presentare lo stesso problema. Sebbene dev e test non abbiano lo stesso volume di record della produzione.

È stato utile?

Soluzione

Il problema, come è stato descritto, sembra derivare da variazioni nel piano di esecuzione di alcune parti nella procedura memorizzata. Guarda quali statistiche vengono conservate nelle tabelle utilizzate e in che modo influiscono sull'aggiunta di nuove righe.

  

Se stai aggiungendo molte righe in   fine dell'intervallo di una colonna (pensa   sull'aggiunta di numeri automatici o   timestamp), l'istogramma per quello   la colonna diventerà rapidamente obsoleta.   Puoi forzare un aggiornamento immediato da   T-SQL eseguendo l'UPDATE   Dichiarazione STATISTICA.

Altri suggerimenti

Ho anche avuto questo problema in cui SPROC impiega pochi secondi per funzionare ma SSRS semplicemente scade.

Ho scoperto dalla mia esperienza che ci sono un paio di metodi diversi per superare questo problema.

  1. Sta annusando i parametri! Quando la procedura memorizzata viene eseguita da SSRS, verrà "sniffata". i tuoi parametri per vedere come il tuo SPROC li sta usando. SQL Server produrrà quindi un piano di esecuzione basato sui risultati. Questo va bene la prima volta che esegui il tuo SPROC, ma non vuoi che lo faccia ogni volta che esegui il rapporto. Quindi dichiaro un nuovo set di variabili nella parte superiore del mio SPROC che memorizza semplicemente i parametri passati nella query e usa questi nuovi parametri in tutta la query.

Esempio:

CREATE PROCEDURE [dbo].[usp_REPORT_ITD001]
@StartDate DATETIME,
@EndDate DATETIME,
@ReportTab INT
AS

-- Deter parameter sniffing
DECLARE @snf_StartDate DATETIME = @StartDate
DECLARE @snf_EndDate DATETIME = @EndDate
DECLARE @snf_ReportTab INT = @ReportTab

... questo significa che quando il tuo SPORC viene eseguito da SSRS sta solo guardando le prime poche righe nella tua query per i parametri passati piuttosto che l'intera query. Ciò riduce notevolmente i tempi di esecuzione in SSRS.

  1. Se il tuo SPROC ha molte tabelle temporanee che sono dichiarate come variabili ( DECLARE @MyTable AS TABLE ), queste sono molto intense sul server (in termini di memoria) durante la generazione di report. Utilizzando invece le tabelle temporanee hash ( SELECT MyCol1, MyCol2 INTO #MyTable ), SQL Server memorizzerà le tabelle temporanee in TempDB sul server anziché nella memoria di sistema, rendendo la generazione di report meno intensiva.

a volte l'aggiunta dell'opzione WITH RECOMPILE all'istruzione CREATE della stored procedure aiuta. Ciò è efficace nelle situazioni in cui il numero di record esplorati dalla procedura cambia nel modo in cui il piano di esecuzione originale non è ottimale.

Fondamentalmente tutto ciò che ho fatto finora è stato ottimizzare un po 'di più lo sproc e sembra almeno risolvere temporaneamente il problema.

Vorrei ancora sapere qual è la differenza tra la chiamata dello sproc da SSMS e SSRS.

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