Sql server 2008 SSRS运行报告30秒,但在SQL Studio中只需3秒

Sql server 2008 SSRS运行报告30秒,但在SQL Studio中只需3秒,sql-server-2008,reporting-services,ssrs-2008,Sql Server 2008,Reporting Services,Ssrs 2008,SSRS报告从SQL 2008调用存储过程,渲染它需要30秒 如果使用相同的参数调用相同的存储过程,则需要3秒才能完成 SQL server和SSR位于同一个框中 我能怎么办 你是在2008 R2上吗?如果是这样的话,请确保应用CU3,R2的问题非常严重。您使用的是2008 R2吗?如果是这样的话,请确保应用CU3,R2有很多错误。我注意到使用设置为调用存储过程的数据集与设置为使用文本SQL查询但文本只调用同一SP的数据集之间存在差异 EXEC custom_sp_name_here 在我所看

SSRS报告从SQL 2008调用存储过程,渲染它需要30秒

如果使用相同的参数调用相同的存储过程,则需要3秒才能完成

SQL server和SSR位于同一个框中


我能怎么办

你是在2008 R2上吗?如果是这样的话,请确保应用CU3,R2的问题非常严重。

您使用的是2008 R2吗?如果是这样的话,请确保应用CU3,R2有很多错误。

我注意到使用设置为调用存储过程的数据集与设置为使用文本SQL查询但文本只调用同一SP的数据集之间存在差异

EXEC custom_sp_name_here
在我所看到的情况中,调用SP的测试SQL查询的性能比将数据集设置为存储过程要好得多


Jamie F

我注意到使用设置为调用存储过程的数据集与设置为使用文本SQL查询但文本只调用同一个SP的数据集之间的区别

EXEC custom_sp_name_here
在我所看到的情况中,调用SP的测试SQL查询的性能比将数据集设置为存储过程要好得多


杰米

抱歉,这不是评论,但这还不是一个选项

你要归还多少张唱片?您是否查看了报表服务器执行表以查看数据检索与呈现所用的时间

如果报告返回了大量页面,则该报告为流式处理。。2个中的1个?还是在呈现第一个页面之前返回所有页面

报告是每次调用时都要花费那么多时间,还是仅仅是第一次,基本上,一旦缓存了计划,它就会快速运行?这可能是因为竞争问题

编辑:对报表服务器数据库运行此脚本。它将为您提供比您想要的更多的信息,但是,如果您按报告名称排序,您可以查看数据检索时间与处理时间或处理和渲染时间的对比。这将告诉您实际占用的时间。此外,默认情况下,报表服务器将保存最后60天,因此,如果您只想说“昨天”,请在where子句中取消对日期间隔的注释

declare 
@ReportPath varchar(200)
,@DayCount int

set @ReportPath = 'ALL'
set @DayCount = -1 * @DayCount

select 
    reverse(substring(reverse(el.ReportPath),1,charindex('/',reverse(el.ReportPath))-1)) as ReportName
    ,u.UserName as LastModBy
    ,coalesce(cast(el.parameters as varchar(max)),'') as [Parameters]
    ,round(datediff(ss,el.TimeStart, el.TimeEnd)/60,0,1) DurationMin
    ,case 
        when datediff(ss,el.TimeStart, el.TimeEnd) > 59 
            then datediff(ss,el.TimeStart, el.TimeEnd) % 60 
        else datediff(ss,el.TimeStart, el.TimeEnd)
    end as DurationSec
    ,case 
        when dt_el2.AvgDuration60Day > 59
            then cast(round(dt_el2.AvgDuration60Day / 60,0,1) as varchar(20)) + ' min ' +  cast((dt_el2.avgduration60day % 60) as varchar(20)) + ' sec' 
        else cast(dt_el2.AvgDuration60Day as varchar(20)) + ' sec'
    end as AvgDuration60Day
    ,case 
        when dt_el2.TotalDuration60Day > 59
            then cast(round(dt_el2.TotalDuration60Day / 60,0,1) as varchar(20)) + ' min ' +  cast((dt_el2.TotalDuration60Day % 60) as varchar(20)) + ' sec' 
        else cast(dt_el2.TotalDuration60Day as varchar(20)) + ' sec'
    end as TotalDuration60Day
    ,case 
        when dt_el2.MinDuration60Day > 59
            then cast(round(dt_el2.MinDuration60Day / 60,0,1) as varchar(20)) + ' min ' +  cast((dt_el2.MinDuration60Day % 60) as varchar(20)) + ' sec' 
        else cast(dt_el2.MinDuration60Day as varchar(20)) + ' sec'
    end as MinDuration60Day
    ,case 
        when dt_el2.MaxDuration60Day > 59
            then cast(round(dt_el2.MaxDuration60Day / 60,0,1) as varchar(20)) + ' min ' +  cast((dt_el2.MaxDuration60Day % 60) as varchar(20)) + ' sec' 
        else cast(dt_el2.MaxDuration60Day as varchar(20)) + ' sec'
    end as MaxDuration60Day
    ,dt_el2.Count60Day
    ,(select count(*) from executionlog2 tmp where tmp.reportpath = el.reportpath and tmp.username = el.username and tmp.reportaction = 'Render' and tmp.status = 'rsSuccess' group by tmp.ReportPath) as UserCount60Day
    ,el.Format
    ,el.UserName
    ,el.ReportAction
    ,el.Status
    ,el.Source
    ,el.[RowCount]
    ,el.ExecutionId
    ,el.TimeDataRetrieval / 1000 as DataRetrieval
    ,el.TimeProcessing / 1000 as Processing
    ,el.TimeRendering / 1000 as Rendering
    ,(el.TimeProcessing + el.TimeRendering) / 1000 as ProcessAndRender
    ,el.AdditionalInfo
    ,case
        when datediff(ss,el.TimeStart, el.TimeEnd) >= 30
            then 1
        else 2
    end as DisplayInRed

from
    ExecutionLog2 el
    join ReportServer.dbo.Catalog c  
        on c.Path = el.ReportPath
    join ReportServer.dbo.Users u  
        on u.UserId = c.ModifiedByID
    join(
            select
                reportpath
                ,sum(datediff(ss,timestart,timeend)) as TotalDuration60Day
                ,max(datediff(ss,timestart,timeend)) as MaxDuration60Day
                ,min(datediff(ss,timestart,timeend)) as MinDuration60Day
                ,avg(datediff(ss,timestart,timeend)) as AvgDuration60Day
                ,count(*) as Count60Day
                --,count(*) over(partition by username) as UserCount60Day
            from
                executionlog2
            where
                reportaction = 'Render'
                and status = 'rsSuccess'
            group by reportpath
        ) dt_el2 on el.ReportPath = dt_el2.ReportPath


where
    (@reportpath = 'ALL' or el.ReportPath = @reportpath)
    --and el.TimeStart between 
        --convert(varchar,dateadd(dd,@daycount,getdate()),112) + ' 00:00:00.000' and
        --convert(varchar,getdate(),112) + ' 23:59:59.000'
    and el.ReportPath != 'Unknown' -- exclude reports that have been deleted after executing
    and el.ReportAction = 'Render'

order by durationmin desc, DurationSec desc;

抱歉,这不是一个评论,但这还不是一个选项

你要归还多少张唱片?您是否查看了报表服务器执行表以查看数据检索与呈现所用的时间

如果报告返回了大量页面,则该报告为流式处理。。2个中的1个?还是在呈现第一个页面之前返回所有页面

报告是每次调用时都要花费那么多时间,还是仅仅是第一次,基本上,一旦缓存了计划,它就会快速运行?这可能是因为竞争问题

编辑:对报表服务器数据库运行此脚本。它将为您提供比您想要的更多的信息,但是,如果您按报告名称排序,您可以查看数据检索时间与处理时间或处理和渲染时间的对比。这将告诉您实际占用的时间。此外,默认情况下,报表服务器将保存最后60天,因此,如果您只想说“昨天”,请在where子句中取消对日期间隔的注释

declare 
@ReportPath varchar(200)
,@DayCount int

set @ReportPath = 'ALL'
set @DayCount = -1 * @DayCount

select 
    reverse(substring(reverse(el.ReportPath),1,charindex('/',reverse(el.ReportPath))-1)) as ReportName
    ,u.UserName as LastModBy
    ,coalesce(cast(el.parameters as varchar(max)),'') as [Parameters]
    ,round(datediff(ss,el.TimeStart, el.TimeEnd)/60,0,1) DurationMin
    ,case 
        when datediff(ss,el.TimeStart, el.TimeEnd) > 59 
            then datediff(ss,el.TimeStart, el.TimeEnd) % 60 
        else datediff(ss,el.TimeStart, el.TimeEnd)
    end as DurationSec
    ,case 
        when dt_el2.AvgDuration60Day > 59
            then cast(round(dt_el2.AvgDuration60Day / 60,0,1) as varchar(20)) + ' min ' +  cast((dt_el2.avgduration60day % 60) as varchar(20)) + ' sec' 
        else cast(dt_el2.AvgDuration60Day as varchar(20)) + ' sec'
    end as AvgDuration60Day
    ,case 
        when dt_el2.TotalDuration60Day > 59
            then cast(round(dt_el2.TotalDuration60Day / 60,0,1) as varchar(20)) + ' min ' +  cast((dt_el2.TotalDuration60Day % 60) as varchar(20)) + ' sec' 
        else cast(dt_el2.TotalDuration60Day as varchar(20)) + ' sec'
    end as TotalDuration60Day
    ,case 
        when dt_el2.MinDuration60Day > 59
            then cast(round(dt_el2.MinDuration60Day / 60,0,1) as varchar(20)) + ' min ' +  cast((dt_el2.MinDuration60Day % 60) as varchar(20)) + ' sec' 
        else cast(dt_el2.MinDuration60Day as varchar(20)) + ' sec'
    end as MinDuration60Day
    ,case 
        when dt_el2.MaxDuration60Day > 59
            then cast(round(dt_el2.MaxDuration60Day / 60,0,1) as varchar(20)) + ' min ' +  cast((dt_el2.MaxDuration60Day % 60) as varchar(20)) + ' sec' 
        else cast(dt_el2.MaxDuration60Day as varchar(20)) + ' sec'
    end as MaxDuration60Day
    ,dt_el2.Count60Day
    ,(select count(*) from executionlog2 tmp where tmp.reportpath = el.reportpath and tmp.username = el.username and tmp.reportaction = 'Render' and tmp.status = 'rsSuccess' group by tmp.ReportPath) as UserCount60Day
    ,el.Format
    ,el.UserName
    ,el.ReportAction
    ,el.Status
    ,el.Source
    ,el.[RowCount]
    ,el.ExecutionId
    ,el.TimeDataRetrieval / 1000 as DataRetrieval
    ,el.TimeProcessing / 1000 as Processing
    ,el.TimeRendering / 1000 as Rendering
    ,(el.TimeProcessing + el.TimeRendering) / 1000 as ProcessAndRender
    ,el.AdditionalInfo
    ,case
        when datediff(ss,el.TimeStart, el.TimeEnd) >= 30
            then 1
        else 2
    end as DisplayInRed

from
    ExecutionLog2 el
    join ReportServer.dbo.Catalog c  
        on c.Path = el.ReportPath
    join ReportServer.dbo.Users u  
        on u.UserId = c.ModifiedByID
    join(
            select
                reportpath
                ,sum(datediff(ss,timestart,timeend)) as TotalDuration60Day
                ,max(datediff(ss,timestart,timeend)) as MaxDuration60Day
                ,min(datediff(ss,timestart,timeend)) as MinDuration60Day
                ,avg(datediff(ss,timestart,timeend)) as AvgDuration60Day
                ,count(*) as Count60Day
                --,count(*) over(partition by username) as UserCount60Day
            from
                executionlog2
            where
                reportaction = 'Render'
                and status = 'rsSuccess'
            group by reportpath
        ) dt_el2 on el.ReportPath = dt_el2.ReportPath


where
    (@reportpath = 'ALL' or el.ReportPath = @reportpath)
    --and el.TimeStart between 
        --convert(varchar,dateadd(dd,@daycount,getdate()),112) + ' 00:00:00.000' and
        --convert(varchar,getdate(),112) + ' 23:59:59.000'
    and el.ReportPath != 'Unknown' -- exclude reports that have been deleted after executing
    and el.ReportAction = 'Render'

order by durationmin desc, DurationSec desc;

最近,我遇到了一个非常类似的问题,一个SQL查询在SSMS上相对较快地返回了大约1000行数据(2秒),但报告本身花费了几分钟来呈现结果

在SSRS中设置报表属性“InteractiveSize”迫使报表对返回的数据进行分页,而不是试图在一个页面中呈现所有内容

这将呈现报告所需的时间减少到3秒


~rantscan

最近,我遇到了一个非常类似的问题,一个SQL查询在SSMS上相对较快地返回了大约1000行数据(2秒),但报告本身却花了几分钟来呈现结果

在SSRS中设置报表属性“InteractiveSize”迫使报表对返回的数据进行分页,而不是试图在一个页面中呈现所有内容

这将呈现报告所需的时间减少到3秒


~rantscan

这就是重点。它像一打记录一样返回,它是一页的报告。。。什么是编译问题?编译什么以及如何找到它?我试图找出您是有渲染问题,还是有sql性能问题。在ssms中执行查询或第一次运行报表时,它将进行编译以找到最佳查询计划,然后缓存它。如果它是一个非常复杂的查询计划,那么编译将花费很长的时间,但是一旦它进入缓存,每次运行它之后,它就会很快,因为您跳过了编译。您可以查看的最佳内容是报表服务器执行表。我将编辑我的答案,给你一个查询,告诉你它的数据是检索还是呈现。这就是重点。它像一打记录一样返回,它是一页的报告。。。什么是编译问题?编译什么以及如何找到它?我试图找出您是有渲染问题,还是有sql性能问题。在ssms中执行查询或第一次运行报表时,它将进行编译以找到最佳查询计划,然后缓存它。如果它是一个非常复杂的查询计划,那么编译将花费很长的时间,但是一旦它进入缓存,每次运行它之后,它就会很快,因为您跳过了编译。您可以查看的最佳内容是报表服务器执行表。我将编辑我的答案,给你一个查询,告诉你它的数据检索或渲染。