9

我有一个表,它是外部 id 和本地 id 之间的映射。

我必须编写一个查询来确定该表是否为双射。我想出了这个

IF 1 <> ANY(
    SELECT COUNT(foreignId)
    FROM mappingTable
    GROUP BY localId
    )
BEGIN
    SELECT 'Oh noes!'
END

ELSE BEGIN
    SELECT 'Everything is fine.'
END

我的主管看了一眼,做了个鬼脸,告诉我我应该写这个:

IF EXISTS(
    SELECT NULL
    FROM mappingTable
    GROUP BY localId
    HAVING COUNT(foreignId) <> 1
    )
BEGIN
    SELECT 'Oh noes!'
END

ELSE BEGIN
    SELECT 'Everything is fine.'
END

我的问题只是这些查询中哪一个更好。我很确定它们是等价的。

4

2 回答 2

12

在 SQL Server 2008 上进行的测试表明,这些查询不仅给出了相同的结果,而且它们甚至具有相同的查询计划。查询优化器已经知道这些查询是等价的。因此,您是对的,任何偏袒一方的论点都必须关注其他方面,例如风格。

就我个人而言,第二个查询更容易理解,尽管第一个查询更接近于用英语表达搜索的方式,因为我看到的EXISTS远不止ANY. 第一个查询让我去“等等,什么?哦,是的,没错……”第二个对我来说是显而易见的。对于其他人(也许对你)来说可能会有所不同;你应该尽量确保你的查询对于你的主管和同事来说很容易阅读。

于 2013-06-27T06:57:26.830 回答
3

您的查询同样糟糕或同样好,具体取决于您的列上是否有索引。

在没有索引的情况下,将对所有行进行表扫描/聚集索引扫描,然后进行哈希匹配以删除重复项。

如果您正在检查的列上有索引,则两个查询都将使用该索引并在发现重复项时提前终止。

带索引的查询计划:

在此处输入图像描述

不带索引的查询计划:

在此处输入图像描述

于 2013-06-27T07:06:30.567 回答