使用带有表变量的IN子句会导致我的查询运行速度变慢

时间:2016-06-27 22:25:47

标签: sql-server reporting-services

我正在使用SSRS报告,我需要将多个参数传递给某些SQL代码。

基于this博文,处理多个参数的最佳方法是使用拆分功能,这就是我所关注的道路。

然而,在我这样做之后,我的表现有些不好。

例如,以下WHERE子句将在4秒内返回数据:

AND DimBusinessDivision.Id IN (
    22
  )

这也将在4秒内正确返回:

DECLARE @BusinessDivisionId INT = 22

  AND DimBusinessDivision.Id IN (
    @BusinessDivisionId 
  )

但是,使用如下所示的拆分功能,需要2分钟(这与没有WHERE子句的时间相同:

  AND DimBusinessDivision.Id IN (
    SELECT Item FROM dbo.FuncSplit(@BusinessDivisionId, ',')
  )

我还尝试在SQL语句之前创建临时表和表变量以及表的结果,但没有区别。我有一种感觉,这与值不是文字值并且SQL服务器不知道要遵循什么样的查询计划或类似的事实有关。有谁知道如何提高这个性能?

即使表具有相同的行数,它也不会像使用表来获取值那样。

更新:我已经使用表函数作为内部联接来解决问题。任何想法,为什么这会产生重大影响?

INNER JOIN
  dbo.FuncSplit(@BusinessDivisionIds, ',') AS FilteredBusinessDivisions ON
  FilteredBusinessDivisions.Item = DimBusinessDivision.Id

1 个答案:

答案 0 :(得分:1)

可以玩的一些事情:

  • 尝试使用非性能查询,并在查询结尾添加OPTION (RECOMPILE);。如果它神奇地运行得更快,那么问题是错误的缓存查询计划。有关此特定问题的详细信息,您可以使用Google"参数嗅探"为了更详尽的解释。

  • 您可能还想查看函数定义并在其中抛出一个RECOMPILE,看看它有什么不同。

  • 查看估算的查询计划并尝试确定差异。

但我认为问题的根源在于你正在用这个"拆分"重新发明轮子。功能。您可以在SSRS中使用多值参数并使用" WHERE col IN @ param":https://technet.microsoft.com/en-us/library/aa337396(v=sql.105).aspx

除非有一个非常具体的原因,你必须拆分逗号分隔列表并且不能使用普通参数,只需使用接受多个值的常规参数。

编辑:我看了你链接的文章。在任何报告工具(不仅仅是SSRS)中都有一个SELECT ALL选项很容易,尽管它并不明显。使用"魔术值"正如您链接到的文章所写的那样工作得很好。我可以问一下有什么限制促使你需要进行字符串拆分吗?