我有一条SQL语句:
select *
from _my_table1
where 1 = 0
and (exists (select 1 from _my_table2 where id =7))执行计划是:
|--Constant Scan现在,当我将查询更改为
Declare @i int = 1
SELECT *
FROM dbo._my_table1
WHERE @i = 0 AND (EXISTS (SELECT 1 FROM dbo._my_table2 WHERE id = 7))我有以下计划:
|--Nested Loops(Left Semi Join)
|--Filter(WHERE:(STARTUP EXPR([@i]=(0))))
| |--Clustered Index Scan(OBJECT:([DEV-RWA_IECMS-DE_Staging_20160301].[dbo].[_my_table1].[PK___my_tabl__3213E83FEF434214]))
|--Clustered Index Seek(OBJECT:([DEV-RWA_IECMS-DE_Staging_20160301].[dbo].[_my_table2].[PK___my_tabl__3213E83F4D4FA6E2]), SEEK:([DEV-RWA_IECMS-DE_Staging_20160301].[dbo].[_my_table2].[id]=(7)) ORDERED FORWARD)问题是,如果第一部分返回false,Server为什么要检查WHERE子句的第二部分。如果第一部分返回false,是否存在强制SQL引擎不检查第二部分位置的解决办法。
发布于 2016-03-09 10:57:40
OPTION (RECOMPILE)是你在这里的朋友。Server不知道在执行时@i的值是什么,所以它编译了一个对任何参数值都有效的计划。
强制重新编译将覆盖该行为,并生成一个具有持续扫描的计划。
示例:
DECLARE @i int = 1;
SELECT *
FROM master.dbo.spt_values
WHERE @i = 0
OPTION (RECOMPILE);如果捕获实际的执行计划,它将只包含一个常量扫描。没有OPTION (RECOMPILE),它包含常规计划。
https://dba.stackexchange.com/questions/131680
复制相似问题