SSRS报告运行速度非常慢,而查询在SSMS中运行速度非常快

时间:2013-04-03 14:36:47

标签: reporting-services

我正在SSRS 2012中运行一个非常基本的报告。我只是从表中检索一些数据,并且我在查询的Where子句中使用了一个参数。如果我在SSRS查询中对参数进行硬编码,但是如果将其作为动态选择的参数保留,则查询将花费5分钟进行渲染,从而快速运行(在不到5秒的时间内)。这是一个类似于我正在使用的抽象查询:

Select Col1, Count(*)
From Tbl1
Where Col2 = @Para1
Group By Col1
OPTION (RECOMPILE);

我已经尝试在查询中使用OPTION(RECOMPILE)来解决参数嗅探问题。我还检查了数据类型,Col2是CHAR(2),Para1是TEXT,因此在运行时不需要转换。

有什么想法会导致这种情况吗?

4 个答案:

答案 0 :(得分:2)

我遇到过类似的问题,但只有连接到Oracle数据库时才会出现问题。当我在查询中对params进行硬编码时....工作得很好.....将参数传递给查询并且它将需要永远。奇怪的是,它只需要永远的某些参数。在我的情况下,当我检查日志时,渲染时间是永远的。 (还应该提到这是一个多选择的参数...无法解决这个问题)

奇怪的解决方案:

我没有将参数传递给查询,而是将其作为过滤器传递给数据集。有人会认为这只会增加ssrs服务器上的负载,因为你要通过线路发送更多数据来处理它...因此增加了渲染时间,但差别是白天和黑夜。该报告现在运行得很好。

老实说无法解释。

我编写的报告数量超出了我对SQL Server数据源的影响,我在连接Oracle时只看到了这个(以及其他一些奇怪的东西)。但是,如果您遇到同样的问题,可能值得一试,而您正在应用的参数并没有实际限制数据。 (无论如何,在我的情况下,大多数人都在运行'全部'。

如果您不熟悉在数据集上使用过滤器。转到此链接并查找标题“使用具有多个值参数的过滤器”(也适用于非多值参数)http://www.mssqltips.com/sqlservertip/2866/sql-server-reporting-services-using-multivalue-parameters/

答案 1 :(得分:1)

我在使用查询加载数据的报告中遇到了类似的问题。就我而言,我必须支持架构团队建立的开发模式(在SSRS DataSet中使用直接查询)。我无法使用过滤器,因为未过滤的数据量和安全要求(仅从数据库中提取请求的数据)。

所以我的解决方案是攻击转换。我声明了表变量,用来自SSRS参数的转换选择值填充这些变量,并在WHERE … IN (…)表达式中使用这些表变量。这涵盖了所有要求仅查询有限数据量安全数据访问并解决了NVARCHAR到VARCHAR转换速度的降低。

查询中的解决方案如下所示(@pSelectedValues变量映射到报表中的选择参数,它在我更改之前就已存在):

DECLARE @tMySelectedParameterValues TABLE( SelectedValue varchar(255) NULL );

INSERT INTO @tMySelectedParameterValues

SELECT DISTINCT EntityStatusStatusName
FROM      dbo.t_MyReferenceData
WHERE     ValueForParameters IN (@pSelectedValues);

... main selection and from parts ....

WHERE keyValues IN (SELECT SelectedValue FROM   @tMySelectedParameterValues )

答案 2 :(得分:0)

三件事:

  1. 为什么必须使用重新编译?除非您的计划特别想在每次不需要时重新考虑它的执行。特别是如果您说明您的查询很简单。 SSRS自己的解释超出了SQL,因此为它添加更多的东西,你只是在寻找麻烦。如果你不得不重新编译,你可能希望将它放在一个proc中,这样所有逻辑都被封装起来供SQL引擎理解。

  2. 参数有时会减慢SSMS参数的查询速度慢吗?你提到它是快速硬编码但没有用参数在SSMS中测试它。我有时看到SSMS上的参数很慢。

  3. 您可以通过一些了解如何“欺骗”SSRS的参数部分。在参数特别糟糕的极端情况下,您可以构建一个在运行时运行的表达式。在数据集选项上,单击表达式的“fx”,然后执行以下操作:

    ="Select Col1, Count(*)
    From Tbl1
    Where Col2 = " & Parameters!Para1.Value
    
  4. 只要您的类型是文本,这应该产生一个合法的字符串,然后在运行时进行评估。一个警告是你的字段可能不会自动填充,所以你可能希望进行实际查询,让它们自动填充,然后返回并将函数放入。否则你必须在左窗格上手动设置字段陈述“领域”的数据集,这是一个痛苦的恕我直言。

答案 3 :(得分:0)

我遇到了同样的问题。我运行了SQL Server Profiler Sniffing queries to SQL Server 确定报告缓慢的位置并找到运行20秒的查询。查询包含在 exec sp_executesql 中。我将查询复制到SSMS,发现它运行20秒。将查询转换为直接SQL使其运行1秒。 AhHah!

返回 exec sp_executesql sql,按预期有一个IN子句:

operid IN  (N''XICL002'',N''XICL005'',N''XICL026'',N''XICL028'...

操作operid是varchar(32),而 N 前缀强制参数为NVARCHAR。删除 N 使得 exec sp_executesql sql在1秒内运行。

在我的情况下,我能够修改报告。 IN子句由多选参数(p_operators)填充。我更改了报表查询,以使用生成p_operators列表的参数从视图中获取operid列表。

operid IN (SELECT oper_id  FROM foo WHERE (foo1 IN (@p_foo1)) AND (foo2 IN (@p_foo2)) AND ...

基本上,将参数从NVARCHAR转换为VARCHAR会破坏性能。似乎SSRS应该提供指示参数数据类型的选项 - 而不仅仅是“文本”。此外,在开发模式下对查询进行一些记录也很不错。

(我希望我提供的信息足够有用。由于公司政策,我不能写太多)

相关问题