我的查询需要返回管道费率不是“禁止使用”的所有使用记录。
What's the difference between NOT EXISTS vs. NOT IN vs. LEFT JOIN WHERE IS NULL?
我已经看到了上述问题,并决定使用IN over EXISTS,因为表中的值可以为空。以下哪一项更好,效率更高,还是有其他比下两种更有效的方式?
SELECT *
FROM usagerecords UR
WHERE UR.usagerateid NOT IN (SELECT id
FROM pipelinerate PR
WHERE PR.name = 'No Usage')
SELECT *
FROM usagerecords UR
WHERE UR.usagerateid IN (SELECT id
FROM pipelinerate PR
WHERE PR.name <> 'No Usage')
答案 0 :(得分:4)
NOT IN
可以为空,那么 id
会给你错误的结果(我希望它不是,否则它有一个可怕的名字)。
当IN
一次又一次地证明EXISTS
效率更高(或至少效率不高)时,为什么会选择EXISTS
而不是IN
,因为它可以缩短电路? SELECT * -- stop doing this
FROM dbo.usagerecords AS UR
WHERE EXISTS
(
SELECT 1 FROM dbo.pipelinerate AS pr
WHERE pr.id = ur.usagerateid
AND pr.name <> 'No Usage'
);
必须实现整个集合。
SELECT * -- again, stop doing this
FROM dbo.usagerecords AS UR
WHERE NOT EXISTS
(
SELECT 1 FROM dbo.pipelinerate AS pr
WHERE pr.id = ur.usagerateid
AND pr.name = 'No Usage'
);
您还可以表达您的其他查询:
SELECT *
但我不知道哪一个得到了正确的结果。这就是我们通常要求提供样本数据和预期结果的原因。
使用IN
可能会比使用EXISTS
或{{1}}对性能产生更大的负面影响。 FWIW。
答案 1 :(得分:0)
“NOT EXISTS与NOT IN和LEFT JOIN之间的区别是什么?”
一旦看到一场比赛,就不会退出。
不是没有。人们开始关注包含大量结果的列表,但是Jeff Moden的一些测试显示它们可以在百万项目范围内正常工作,这通常就足够了。
基于null的左连接是基于设置的,因此它是“经典”解决方案。 “在”基本上变成了巨人或名单。当你只是测试错过的东西时,左连接where null没有任何特定的优点,当我正在寻找每个用户最近的事件时,我喜欢使用左自连接/是空模式。 / p>
不是非常简单,任何新手开发人员都会理解它的作用。
不存在几乎一样清楚,但可能高于新手。
即使是中级开发人员,左连接/为空也常常被误解。所以我个人认为不是最容易维护的。