繁体   English   中英

SQL Server:“布尔” WHERE子句中的子查询

[英]SQL Server: Subquery in “boolean” WHERE clause

我有使用以下结构的T-SQL查询(SQL Server 2008/2012):

WHERE (@param1 IS NULL OR column1 = @param1)
AND (@param2 IS NULL OR column2 = @param2)
AND (@param3 IS NULL OR column3 = @param3)

这可以很好地工作,并使用NULL参数自动优化WHERE子句中所有AND'ed部分。

但是,当我对子查询执行相同的操作时,即使参数为NULL,优化器似乎仍会执行子查询:

WHERE 
    (@param1 IS NULL OR column1 IN (SELECT column 
                                    FROM table 
                                    WHERE column = @param1))
    AND (@param2 IS NULL OR column2 IN (SELECT column 
                                        FROM table 
                                        WHERE column = @param2))
    AND (@param3 IS NULL OR column3 IN (SELECT column 
                                        FROM table 
                                        WHERE column = @param3))

我的问题是,为什么优化程序甚至会考虑“ IN”选择,因为参数为NULL的事实应该已经“短路”了查询的那一部分?

@ user640466:我认为如果您添加OPTION(RECOMPILE)查询提示,则错误的计划将会消失,原因是查询优化器必须评估IN子句以获取ProductID值,而在OPTION(重新编译)的情况下,它可能会嗅探运行时间值。 请在下面看到Adventure Works的工作副本:

CREATE PROC MyTest
@ProductID INT ,
@Name NVARCHAR(50),
@ProductNumber NVARCHAR(50)
AS
SELECT * 
FROM Production.Product 
WHERE 
(ProductID IN (SELECT ProductID FROM Production.Product WHERE ProductID = @ProductID ) OR @ProductID IS NULL)
AND 
(Name IN (SELECT Name FROm Production.Product WHERE Name = @Name) OR @Name IS NULL)
AND 
(ProductNumber IN (SELECT ProductNumber FROM Production.Product WHERE ProductNumber = @ProductNumber)  OR @ProductNumber IS NULL)
--OPTION (RECOMPILE)
GO 

如果执行Proc:EXEC Mytest 1,NULL,NULL,将得到一个冗长的计划,但是更改sp并取消注释OPTION(RECOMPILE),将得到一个不错的计划。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM