Por que um relatório SSRS tempo quando o procedimento armazenado é baseado em retornos de resultados em poucos segundos?

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

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.

Foi útil?

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.

  1. É 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.

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top