[英]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.