【问题标题】:Terrible performance in SSRS 2012SSRS 2012 的糟糕表现
【发布时间】:2013-06-11 22:22:05
【问题描述】:

SSRS 2012 中的 SPLIT(JOIN()) 函数是否存在问题?

这就是我问的原因...

我刚刚设置了一个 SSRS 2012 服务器。我有一个在 SSRS 2008 R2 中构建的现有报告,它从 2005 年的数据库中提取。我在 MVS 2010 中创建了一个新项目并添加了现有的 rdl。

当我预览报告时,性能至少比我在 MVS 2008 中预览时差 5 倍。我跑了一个跟踪,发现 SSRS 甚至执行 SP 都需要相当长的时间。一旦完成,它就会快速渲染。

我试图想出一些可能会减慢 SP 执行速度的方法。我想出的唯一一件事是我有很多多值参数,我使用 SPLIT(JOIN()) 函数传递给 SP。那些在 2012 年被新的东西取代了吗?如果没有,我什至不知道从哪里开始寻找问题。我最初的谷歌搜索没有出现。

有没有人遇到过这个问题,或者知道一些在 2008 年运行良好但在新版本中运行不佳的事情列表?

我希望这个问题不要太含糊。感谢阅读!

编辑:我觉得很傻。我刚刚追踪了 2008 年的报告执行情况,结果发现它做了同样的事情,这是我以前从未注意到的。 SP 出现在 Profiler 中后,渲染速度非常快。所以......我不知道问题可能是什么。任何帮助将不胜感激!

【问题讨论】:

  • 你为什么要首先进行拆分连接?根据我对 SSRS 的经验,速度的最终破坏者是过度使用 SSRS 函数,当它们不需要或可以通过以下方式完成时: 1. 代替 SQL 2. 代替代码中的一些 VB.NET。在很多情况下,当我经常使用函数时,我已经看到性能从几秒钟缩短到几分钟。您能否详细说明为什么需要执行这些功能?此外,我也多次看到在开发机器上调试一段代码比在实际服务器上调试功能要慢。
  • 我有8个多值参数,都需要传入主存储过程。我不知道如何在不使用 SPLIT JOIN 的情况下传递一组选择。很抱歉,当谈到 VB.NET 时,我是一个 luddite。我记得看到过一些关于定义自定义代码来实现这一点的东西,但我没有意识到性能会如此不同,所以我没有费心去学习。你指的是这个吗?
  • 我是 C# 而不是 VB.NET,但通常您可以使用 mult 值和诸如“where column in (@multiValue)”之类的谓词来做您需要的事情。我不确定这是否适用于过程或函数,但它适用于查询。
  • 您需要一个 SPLIT JOIN(或 .NET 代码)将多值数组转换为逗号分隔的字符串。如果不这样做,IN 将无法工作。
  • 它将与选择查询一起使用,我一直在我的 SSRS 中使用多值参数来执行此操作。当我设置一个多值参数时,用户,如下所示:选择“约翰”作为用户联合选择“布雷特”联合选择“比尔”并将其设置为“从查询中获取值”的参数。然后我可以在我的主数据集中执行此操作:select * from users where user in (@Users)。

标签: reporting-services


【解决方案1】:

我会坚持使用如下谓词:

Where thing in (@Sets)

“Sets”变量可能来自我创建的从 SQL 获得的另一个数据集,例如:

Select 'Brett' as Name
Union
Select 'Anna'
Union
Select 'John'
Union
Select 'Jenny'

简单地选择从“从数据集中获取数据”中获取集合的数据。设置变量后,SQL 2008R2 及更高版本应该为您解决问题,找出 Where thing in (@Sets) 表达式中谓词的子句实际转换为:

Where thing in ('Brett', 'Anna', 'John', 'Jenny')

【讨论】:

    【解决方案2】:

    加快 SSRS 报告速度和减少服务器负载的主要解决方案是缓存报告。如果这样做(例如,我在早上 7:30 预加载缓存)或缓存命中的报告,则会发现加载速度大幅提升。

    请注意,我每天都在专业地这样做,而不仅仅是在 SSRS 上写诗

    SSRS 中的缓存 http://msdn.microsoft.com/en-us/library/ms155927.aspx

    预加载缓存 http://msdn.microsoft.com/en-us/library/ms155876.aspx

    如果您不喜欢需要很长时间的初始报告并且您的数据是静态的,即每日总账等,这意味着数据在一天内相对静态,您可以延长缓存的使用寿命

    最后,您也可以选择让业务经理改为通过电子邮件订阅接收这些报告,这将向他们发送一份 Excel 时间点报告,他们可能会觉得更容易并且更加系统化。

    您还可以在 SSRS 中使用参数,以便用户轻松解析并加快查询速度。在查询生成器中,在您希望参数化的过滤器列下键入 IN(@SSN),然后您将在 BIDS GUI 左上角的数据源上方的参数文件夹中找到它。 [如果在 SSRS 中没有看到数据源部分,请按 CTRL+ALT+D。

    在此处查看几乎相同的问题:Performance Issuses with SSRS

    【讨论】:

      【解决方案3】:

      创建一个 UDF,它将采用逗号(或您要使用的其他分隔符)分隔的列表,并返回一个您可以加入的表。

      https://blogs.msdn.microsoft.com/amitjet/2009/12/11/convert-comma-separated-string-to-table-4-different-approaches/

      然后你可以在你的存储过程中设置一个参数,比如@TheList varchar(max)

      然后您应该能够在 JOIN 中使用它,使用它来创建一个临时表,然后在您的查询中加入它,或者将其用作子选择。

      我们经常使用它,发现如果您主要使用整数值,那么返回的表应该是 INT 表以提高性能。

      伪例子:

      declare @TheList varchar(max)
      
      set @TheList = ('1,2,3,4,5,6,7,8')
      
      select *
      from dbo.MyRecords r
      join dbo.udf_CreateArrayTable(@TheList) at on r.RecID = at.RecID
      

      【讨论】: