Por que um relatório SSRS tempo quando o procedimento armazenado é baseado em retornos de resultados em poucos segundos?
-
04-07-2019 - |
Pergunta
Eu tenho um relatório que processa dados retornados de um procedimento armazenado. Usando profiler eu posso pegar a chamada para o procedimento armazenado a partir dos serviços de informação.
O relatório não informando o relatório expirou ainda posso executar o procedimento armazenado de SSMS e ele retorna a parte de trás de dados em cinco a seis segundos.
Note, no exemplo de execução de teste apenas duas linhas são retornadas para o relatório para renderização embora dentro do procedimento armazenado pode ter sido a trabalhar ao longo de milhares ou mesmo milhões de registros, a fim de reunir o resultado passado de volta para os serviços de informação.
Eu sei que o procedimento armazenado pode ser otimizado mais, mas eu não entendo por que SSRS seria o tempo limite quando a execução só parece demorar alguns segundos para executar a partir SSMS.
Também outro problema veio à tona. Se eu recriar o procedimento armazenado, o relatório começa a tornar perfeitamente bem novamente. Que está bem, exceto depois de um curto período de tempo, o relatório começa o tempo limite novamente.
O retorno do out parece estar relacionada com novos dados a ser adicionado na tabela principal do relatório está correndo contra. No exemplo eu estava testando, apenas cem novos recordes sendo inserido foi o suficiente para estragar o relatório.
Eu imagino mais corretamente não é o relatório que é a causa raiz. É o procedimento armazenado que está causando o tempo limite quando executado a partir SSRS.
Uma vez que é timeing para fora outra vez, eu melhor solução que tenho até agora é recriar o procedimento armazenado. Este não parece ser uma solução ideal.
O problema também só parece estar ocorrendo em nosso ambiente de produção. Nossas plataformas de teste e desenvolvimento não parecem estar apresentando o mesmo problema. Embora dev e teste não tem o mesmo volume de registros como a produção.
Solução
O problema, como você descreveu, parece vir de variações sobre o plano de execução de algumas partes em seu procedimento armazenado. Olhe para o que as estatísticas são mantidos nas tabelas usadas e como a adição de novas linhas afetá-los.
Se você está adicionando um monte de linhas no fim do intervalo de uma coluna (pensar sobre a adição de AutoNumbers, ou timestamp), o histograma para esse coluna vai tornar-se rapidamente ultrapassada. Você pode forçar uma atualização imediata de T-SQL, executando o UPDATE ESTATÍSTICAS comunicado.
Outras dicas
Eu também tive esse problema em que a SPROC leva alguns segundos para executar ainda SSRS simplesmente vezes fora.
Eu descobri por experiência própria que há um par de métodos diferentes para superar esse problema.
- É parâmetro sniffing! Quando o procedimento armazenado é executado a partir SSRS ele vai "farejar" os seus parâmetros para ver como seu SPROC é usá-los. SQL Server, então, produzir um plano de execução com base em suas conclusões. Isso é bom na primeira vez que executar o seu SPROC, mas você não quer que ele estar fazendo isso cada vez que você executar o seu relatório. Então eu declarar um novo conjunto de variáveis ??no topo das minhas de Sproc que simplesmente armazenam os parâmetros passados ??na consulta e utilizar estes novos parâmetros em toda a consulta.
Exemplo:
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
... Isto significa que quando o seu SPORC é executado pelo SSRS é apenas olhando para as primeiras filas em sua consulta para os parâmetros passados ??ao invés de toda a sua consulta. O que reduz o tempo de execução consideravelmente nos SSRS.
- Se o seu SPROC tem um monte de tabelas temporárias que são declaradas como variáveis ??(
DECLARE @MyTable AS TABLE
), estes são realmente intensivo no servidor (em termos de memória) ao gerar relatórios. Usando tabelas temporárias de hash (SELECT MyCol1, MyCol2 INTO #MyTable
) em vez, SQL Server irá armazenar suas tabelas temporárias no TempDB no servidor em vez de no memeory sistema, tornando a geração de relatórios menos intensiva.
algum acrescentando opção WITH RECOMPILE para a instrução CREATE de procedimento armazenado ajuda. Isto é eficaz em situações em que o número de registros explorado pelo procedimento mudanças na maneira que o plano de execução original não é o ideal.
Basicamente tudo o que eu fiz até agora foi otimizar a sproc um pouco mais e parece, pelo menos temporariamente resolver o problema.
Ainda assim, gostaria de saber qual é a diferença entre chamar o sproc do SSMS e SSRS.