我有一张左表和一张右表,两张表都有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)
这是值列不为空的计划
现在,当将列值从非null更改为null时,我得到完全不同的计划。有人能解释我这个计划吗?为什么表t_right被扫描两次以及为什么行计数假脱机操作符显示在计划中。这使查询变得昂贵。我需要有人帮助我理解这两种情况下的计划 - 当列不为空且列为空时。
alter table t_left
alter column value int null
我知道当列为空时我应该使用notexists。但是为什么不在两种情况下表现不同