where 子句中使用的 SQL Server 查询性能视图

Posted

技术标签:

【中文标题】where 子句中使用的 SQL Server 查询性能视图【英文标题】:SQL Server Query performance view used in where clause 【发布时间】:2017-02-02 13:43:36 【问题描述】:

我在 sql server 中的查询有问题。

我在 where 子句中使用了一个视图

SELECT ... 
FROM T1
WHERE 
(@param = 1 AND EXISTS (SELECT 1 FROM VIEW...)) // in this case => use view
OR
(@param = 2 AND T1.Id = ...) // in this case => no view

我在执行计划中看到始终构建视图。但我不想那样。

有什么想法吗?

【问题讨论】:

如果您在查询中引用视图,则此视图始终为构建 ..(动态生成)查询无法部分执行 .. 【参考方案1】:

如果您不希望在不需要时构建视图,则使用动态 SQL 并在需要或不需要时有条件地启用和禁用视图部分。类似的东西:

declare @useView nvarchar(max) = '--'

if (@param = 1)
set @useView = ''

declare @sql nvarchar(max) = '
SELECT ... 
 FROM T1
 WHERE 1=1 '
 + @useView ' AND EXISTS (SELECT 1 FROM VIEW...)) -- in this case => use view '
+'
 AND
 (@p_param = 2 AND T1.Id = ...) -- in this case => no view '

print @sql
exec sp_executesql @sql,N'@p_param INT',@p_param = @param

您需要确保引用 VIEW 的整个 SELECT 适合 1 行以被 -- 注释覆盖,否则为 /**/ 使用 2 个注释变量。

【讨论】:

这正是我想要的。只需在需要时构建视图 我会尝试...这是 Reporting Services 报告中的一个查询,然后我希望动态 SQL 可以与 s-s-rS 一起使用。 @L.Toto 尝试一下并告诉我。但首先,在 SSMS 中创建一个有效的查询,并确保它在您手动运行时运行没有错误。 @L.Toto 只是好奇您是否设法将此动态 SQL 附加到您的 s-s-rS 报告中? 我创建了一个在我的 s-s-rS 报告中调用的存储过程。【参考方案2】:

将参数值检查移动到子查询中,然后查询优化器应该能够构建更好的计划:

SELECT ... 
FROM T1
WHERE 
(EXISTS (SELECT 1 FROM VIEW ... WHERE ... @param = 1)) // in this case => use view
OR
(@param = 2 AND T1.Id = ...) // in this case => no view

【讨论】:

以上是关于where 子句中使用的 SQL Server 查询性能视图的主要内容,如果未能解决你的问题,请参考以下文章

使用 SQL Server 2008 在 WHERE 子句中使用 SUBSTRING 函数 [重复]

无法在 SQL Server 2008 中使用 where 子句获取 nvarchar 类型数据

如何在 SQL Server 的 Where 子句中使用 case 语句

当 WHERE 子句中只有一列时,SQL Server 会使用复合索引吗?

如何在 SQL Server where 子句中使用表值函数

XML 值的 SQL Server Where 子句路径