为什么不在可空列中的地方获得不同的执行计划而不是非空的列

时间:2016-03-30 18:55:28

标签: sql-server

我有一张左表和一张右表,两张表都有100万条记录 -

CREATE TABLE t_left (
id INT NOT NULL PRIMARY KEY,
value INT NOT NULL)

CREATE TABLE t_right (
id INT NOT NULL PRIMARY KEY,
value INT NOT NULL
)

t_left表的示例数据是 -

id  value
10000   1
20000   1
30000   1
40000   2
50000   2
60000   2

t_right表的示例数据是 -

id  value
2   2
3   2
4   2
5   2
6   2

现在我想找到表t_right

列“值”中不存在列“值”的t_Left的所有行

所以我的输出应该是

id  value
10000   1
20000   1
30000   1

现在我的问题是当t_left表的列“Value”为NOT NULL时,sql server生成不同的计划,并且当“Value”列为null时,计划的计划非常不同。所以按照上面的表定义我的查询计划 -

select a.id,a.value 
from dbo.t_left as a
where a.value not in (select b.value from t_right as b)

这是值列不为空的计划

this is the plan when value column is not null

现在,当将列值从非null更改为null时,我得到完全不同的计划。有人能解释我这个计划吗?为什么表t_right被扫描两次以及为什么行计数假脱机操作符显示在计划中。这使查询变得昂贵。我需要有人帮助我理解这两种情况下的计划 - 当列不为空且列为空时。

alter table t_left
alter column value int null

enter image description here

我知道当列为空时我应该使用notexists。但是为什么不在两种情况下表现不同

0 个答案:

没有答案