2

我的查询需要返回管道速率不是“无使用”的所有使用记录。

NOT EXISTS vs. NOT IN vs. LEFT JOIN WHERE IS NULL 之间有什么区别?

我已经看到了上述问题,并决定使用 IN 而不是 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') 
4

2 回答 2

4

NOT IN如果id可以为空(我希望它不是,否则它的名字很糟糕)会给你错误的结果。

当一次又一次地证明IN效率更高(或至少效率不低)时,你为什么要选择它,因为它可以短路?必须实现整个集合。EXISTSEXISTSIN

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 *可能会对性能产生更大的负面影响。FWIW。INEXISTS

于 2013-04-18T15:55:55.877 回答
0

“NOT EXISTS vs. NOT IN vs. LEFT JOIN WHERE IS NULL 之间有什么区别?”

Not exists 会在看到一个匹配项后立即退出。

不在不。人们会担心包含大量结果的列表是否包含在内,但 Jeff Moden 的一些测试表明,它们可以正常工作到百万个项目范围,这通常就足够了。

Left join where is null 是基于设置的,所以它是“经典”解决方案。“在”基本上变成了一个巨人或列表。当您只是在测试遗漏的东西时,左连接 where is null 没有任何特定优势,我喜欢在寻找每个用户的最新事件时使用左自连接/为 null 模式。

Not in 超级简单,任何新手开发者都会明白它的作用。

不存在几乎一样清楚,但可能高于新手。

Left join/is null 经常被中级开发人员误解。所以我个人发现不是最可维护的。

于 2013-04-18T16:04:01.753 回答