7

相当多的数据库脚本具有以下形式:

IF NOT EXISTS(SELECT * FROM Countries WHERE Name = 'France')
INSERT INTO(Countries)

但是,我也看到人们这样做:

IF NOT EXISTS(SELECT CountryID FROM Countries WHERE Name = 'France')
INSERT INTO(Countries)

乃至:

IF NOT EXISTS(SELECT 1 FROM Countries WHERE Name = 'France')
INSERT INTO(Countries)

据说最后一个的优点是效率更高:查询实际上不使用子查询中的任何列,因此不带回任何列可能会更快。但它看起来很奇怪,所以我觉得它可能会让一些人感到困惑。它对实际执行时间有什么影响吗?

4

3 回答 3

10

我认为是在 SQL Server 的 6.5 - 7 时期,他们使查询优化器足够聪明地知道:

IF NOT EXISTS(SELECT * FROM Countries WHERE Name = 'France')

实际上不需要返回任何行数据。使用的建议SELECT 1早于那个日期,但仍作为一个神话继续存在。

可以说,这是 SQL 标准的一个错误——它们应该允许EXISTSFROM子句开始并且根本没有SELECT部分。


带有 EXISTS 的子查询

EXISTS 引入的子查询的选择列表几乎总是由星号 (*) 组成。没有理由列出列名,因为您只是在测试满足子查询中指定条件的行是否存在。

于 2013-10-23T13:54:46.610 回答
3

不,sql server 足够聪明,可以为您进行这种优化。

于 2013-10-23T13:54:23.450 回答
3

不。唯一重要的是是否返回行,这就是 SELECT 1 足够好的原因。

于 2013-10-23T13:55:33.913 回答