首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SQL Server:"boolean“WHERE子句中的子查询

SQL Server:"boolean“WHERE子句中的子查询
EN

Stack Overflow用户
提问于 2014-09-11 10:28:43
回答 1查看 743关注 0票数 0

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

代码语言:javascript
复制
WHERE (@param1 IS NULL OR column1 = @param1)
AND (@param2 IS NULL OR column2 = @param2)
AND (@param3 IS NULL OR column3 = @param3)

这可以很好地工作,并自动优化WHERE子句中带有NULL参数的and‘’ed部分。

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

代码语言:javascript
复制
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))

我的问题是,既然参数为NULL的事实应该已经“短路”了查询的那一部分,为什么优化器还要考虑"IN“SELECT呢?

EN

回答 1

Stack Overflow用户

发布于 2014-09-11 11:44:11

@user640466:我认为如果添加OPTION (RECOMPILE)查询提示,坏计划就会消失,原因是查询优化器必须评估IN子句来获得ProductID值,而在OPTION (recompile)的情况下,它可以嗅探运行时值。请看下面一份来自Adventure的工作副本:

代码语言:javascript
复制
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并取消注释选项(重新编译),您将获得很好的计划。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25778106

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档