48

我有一些 .NET 代码以适中的间隔检查是否存在 SQL 记录。我希望让这张支票尽可能“便宜”。

我想知道两个查询的特征:

IF EXISTS(SELECT 1
          FROM   BigTable
          WHERE  SomeColumn = 200)
  SELECT 1 AS FOUND
ELSE
  SELECT 0 AS FOUND

VS

SELECT TOP 1 1
FROM   BigTable
WHERE  SomeColumn = 200 

它们都产生相似的执行计划。但是 SELECT TOP 1 1 似乎执行得更快:要解析的查询更少,当找不到记录时,它发送的管道更少。我还假设它在客户端运行得更快,因为我只需要检查记录计数,而不是编组 IF EXISTS 的返回值。

大多数性能优势都可以忽略不计。但是,如果两者始终返回相同的结果,那么为什么不选择稍微快一点的方法呢?

“SELECT TOP 1 1”是检查 .NET 中是否存在记录的最佳方式吗?

(我们使用 .NET 3.5,我试图避免使用 LINQ,因为它没有在应用程序的其他地方使用。我们还有一些正在迁移/重写的遗留 VB6 应用程序,因此它们可能也需要执行此操作。)

编辑:关于设计的更多细节。该记录是一个“标题”。当找到此标头时,还有另一个包含子记录的表将被读取/解析。没有记录是一件好事:没有工作要做。

EDIT2:缺少满足条件的记录会更频繁地发生。他们以零星的浪潮出现。

4

5 回答 5

40

我建议使用IF EXISTS(SELECT * ...),除非这实际上会导致性能问题。它以比替代方式更好理解的方式表达了查询的意图。

除非您确实需要表中的行数,否则我会避免COUNT(*)(如在当前答案中) 。

如果您想要从结果中检查行数的“效率”,我可能会选择:

select 1 where exists(select * from BigTable where SomeColumn=200)

这会产生与您的第二个查询相同的结果集(0 或 1 行)

于 2012-06-13T06:14:54.093 回答
15

这是你想要的,而不是 IF 语句

  SELECT ISNULL(
     (SELECT TOP 1 1 FROM BigTable where SomeCol = 200), 0);
于 2012-06-13T06:12:21.973 回答
7

根本没有区别,exists 甚至不会评估您语句的选择部分。所以,用你喜欢的那个。

declare @test table (name varchar(20))

-- comment out inserts for testing.
insert into @test (name) values ('bob the builder')
insert into @test (name) values ('bob the builder')

-- for giggles, put 1/0 here. You'll find that divide by zero error.
select 1 from @test

-- notice that you don't receive a divide by zero error.
-- the bit in the select portion is never executed, ever.
if not exists (select 1/0 from @test) select 'Yay!'
if     exists (select 1/0 from @test) select 'Boo!'

事实上,您可以互换使用这些:

... select * ... 
... select 1 ... 
... select top 1 * ... 
... select top 1 1 ... 
... select 'John Jacob Jingleheimer Schmidt' ... 
于 2019-02-06T20:21:53.607 回答
2

我肯定会选择第二个选项:

SELECT TOP 1 1
FROM   BigTable
WHERE  SomeColumn = 200 

即使 I/O 和 CPU 数量基本相同,执行计划也更简单高效。

于 2013-09-30T21:17:36.170 回答
-16

不确定 SQL Server,但在其他数据库中,标准方法是:

SELECT COUNT(*) FROM BigTable where SomeCol = 200;

实际效率取决于您的索引等。

于 2012-06-13T06:06:32.113 回答