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 很大,适当的索引会有所帮助。
我有一个包含 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 很大,适当的索引会有所帮助。