【问题标题】:Conditional OR in the SQL Server Join – Multi-Value ParametersSQL Server 连接中的条件 OR - 多值参数
【发布时间】:2015-10-10 04:28:10
【问题描述】:

我有一个包含 4 个参数的 SSRS 报告,其中两个是多值参数(@material@color 在 SQL Server 2008 R2 中使用 VARCHAR(MAX) 数据类型)。我正在使用拆分函数以逗号分隔的形式返回值:

SELECT * 
FROM MyView
WHERE height > 200
    AND width > 100
    AND (
        material IN (SELECT Item FROM [dbo].[MySplitFunction] (@material, ',')) OR
        color IN (SELECT Item FROM [dbo].[MySplitFunction] (@color, ','))
        )

(上面的代码将返回 50 条记录)

这种方法的问题在于,这两个多值参数有大约 1,500 种不同的颜色和材料,会降低性能。有时,返回结果需要超过 40 分钟(视图中的行数约为 600,000)。

我尝试了一种不同的方法,我使用了一个临时表,并在 JOIN 而不是 WHERE 子句中使用它:

SELECT Item
INTO #TempTable
FROM [dbo].[MySplitFunction] (@material, ',')

SELECT  * 
FROM MyView 
INNER JOIN ON MyView.Item = #TempTable.Item
WHERE height > 200
    AND width > 100
    AND material IN (SELECT Item FROM [dbo].[MySplitFunction] (@material, ','))

(上面的代码只返回 7 条记录,但性能要好得多) 我的问题是如何通过添加另一个 @color 参数并允许 OR 条件使用第二种方法返回相同数量的记录(50 行)?所以在 SSRS 报告中,用户可以多选这两个参数,查询将返回@material = values OR @color = Values。 我对任何其他方法持开放态度,只要它能加快查询速度并允许两个多值参数(@material、@color)的 OR 条件。

谢谢!

【问题讨论】:

  • 它是 SQL Server 2008 R2。谢谢!

标签: sql-server-2008-r2 ssrs-2008-r2


【解决方案1】:

类似下面的东西可能会奏效。我不确定我的语法是否完全正确,它需要进一步的测试和分析,如果没有正确的结构和数据,我就无法做到……

SELECT
 from MyVeiew
 where height > 200
  and width > 100
  and (exists (select Item
                from dbo.MySplitFunction(@material, ',')
                where Item = material)
       or exists (select Item
                   from dbo.MySplitFunction(@color, ',')
                   where Item = color)
      )

这会对嵌套函数调用执行两个相关的子查询。在这些情况下,Exists 检查通常比 in 查找更快。令我担心的语法位是“and (exists”) 位——这是 OR 子句的括号,与 exists 结合起来看起来有点不靠谱。

我认为它应该做你想做的,但绝对需要测试。


我不相信or 子句。要摆脱它,试试这个,看看会发生什么:

SELECT *  --  Better with specific columns
 from MyView
 where height > 200
  and width > 100
  and exists (select Item
                from dbo.MySplitFunction(@material, ',')
                where Item = material)
UNION select *
 from MyView
 where height > 200
  and width > 100
  and exists (select Item
                   from dbo.MySplitFunction(@color, ',')
                   where Item = color)

这会运行并组合两个查询,删除所有重复项——与 OR 子句几乎相同。

接下来要检查的是检查表大小和检查索引。您正在(仅!)列高度、宽度、材料和颜色上过滤结果;如果表很大,适当的索引会有所帮助。

【讨论】:

  • 感谢您的提示。它执行得很好,但性能略有提升,大约需要 39 分钟才能得到结果。还有其他建议吗?
  • 我恳求信息不足。在这种情况下,我会查看索引定义和执行计划,并做一堆“边走边编”的查询来解决问题。 (最终,可能是因为您在那里有 or 子句。事实上......检查上面的编辑。)
  • 谢谢菲利普!工会需要更多时间来执行。问题在于拆分功能,因为它占用了超过 80 的执行时间。这是一个基于 5 个不同表的视图。我使用的是列名而不是 *.从视图中选择所有列需要不到一分钟的时间。一旦我添加了拆分功能,执行时间就会变得非常高。 Sql & SSRS 中的拆分功能有什么技巧/窍门改进吗?
  • Stack Overflow 上发布了几十个(至少)sql“拆分函数”。最好的建议是查找一些内容并与您的操作方式进行比较。另一个尝试的选项:创建临时表,使用函数加载它们,并在查询中使用临时表。
  • 另一件事,如果您使用的是多语句表函数,请不要。许多专家讨厌它们,因为如果在复杂查询中使用它们会破坏性能。 (根据我之前的评论,足以安全地用于填充临时表。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-17
  • 1970-01-01
  • 1970-01-01
  • 2022-10-15
  • 2017-06-11
  • 1970-01-01
相关资源
最近更新 更多