SQL 服务器连接中的条件或 - 多值参数

Conditional OR in the SQL Server Join – Multi-Value Parameters

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

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, ','))
        )

(上面的代码会 return 50 条记录)

这种方法的问题是这两个多值参数有大约 1,500 种不同的颜色和 materials 并且降低了性能。有时,return 结果需要 40 多分钟(视图中的行数约为 600,000)。

我尝试了一种不同的方法,我使用临时 table 并在 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, ','))

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

的 OR 条件

谢谢!

像下面这样的东西可能会起作用。我不确定我的语法是否完全正确,它需要进一步的测试和分析,如果没有正确的结构和数据我就无法做到...

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 子句几乎相同。

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