Sql server 2005 :- IF EXISTS 和 COUNT(*) > 0 的 IO 统计信息是不是相同?

Posted

技术标签:

【中文标题】Sql server 2005 :- IF EXISTS 和 COUNT(*) > 0 的 IO 统计信息是不是相同?【英文标题】:Sql server 2005 :- IO statistics for both IF EXISTS and COUNT(*) > 0 Same?Sql server 2005 :- IF EXISTS 和 COUNT(*) > 0 的 IO 统计信息是否相同? 【发布时间】:2010-10-29 10:26:15 【问题描述】:

编辑:-

对于 EXISTS 和 COUNT(*) > 0,生成以下 Id 列上的 PK

Table 'TableWithHugeData'. Scan count 0, logical reads 3, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

IF OBJECT_ID('TableWithHugeData') IS NOT NULL
BEGIN
DROP TABLE TableWithHugeData
END

CREATE TABLE TableWithHugeData
(
ID UNIQUEIDENTIFIER,
Name varchar(max)
)


DECLARE @Counter INT
SELECT @Counter = 0
WHILE (@Counter < 50000)
BEGIN
INSERT INTO TableWithHugeData
VALUES (NewId(),'Ashish ' + Convert(varchar(5000),@Counter))
SELECT @Counter = @Counter +1
END

存在

DBCC FreeProcCache
DBCC DROPCLEANBUFFERS
SET  STATISTICS IO ON
DECLARE @Id UNIQUEIDENTIFIER
SELECT @Id = '28BD1F4C-7D89-4731-9D2C-21ECB20500F8'
IF EXISTS (SELECT * FROM TableWithHugeData WHERE Id = @Id)
BEGIN
SELECT CONVERT(BIT, 1)
END
ELSE
BEGIN
SELECT CONVERT(BIT, 0)
END

EXISTS 的 IO 统计数据:-

表'TableWithHugeData'。扫描计数 1,逻辑读取 6,物理读取 1,预读读取 270,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。

COUNT(*) >0

DBCC FreeProcCache
DBCC DROPCLEANBUFFERS
DECLARE @Id UNIQUEIDENTIFIER
SELECT @Id = '28BD1F4C-7D89-4731-9D2C-21ECB20500F8'
IF (SELECT COUNT(*) FROM TableWithHugeData WHERE Id = @Id)>0
BEGIN
SELECT CONVERT(BIT, 1)
END
ELSE
BEGIN
SELECT CONVERT(BIT, 0)
END

*IO 统计 Count() >0 ** :-

表'TableWithHugeData'。扫描计数 1,逻辑读取 6,物理读取 1,预读读取 270,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。

如您所见,EXISTS 和 COUNT(*)>0 的 IO 统计信息是相同的。我认为 EXISTS 会更快并且执行更少的读取。我在这里错过了什么吗?定义主键会有什么不同吗?

【问题讨论】:

没有索引,如果没有找到值或在表的末尾... 对不起。我刚刚从表中选择了一个值并尝试在表中找到相同的值。它在桌子上。我应该提出一个查询来获取它以便简单运行。 【参考方案1】:

如您所见,EXISTS 和 COUNT(*)>0 的 IO 统计信息是相同的。我认为 EXISTS 会更快并且执行更少的读取。我在这里遗漏了什么吗?

SQL Server 按块读取数据。

如果您要查找的记录恰好在最后一个块中(或根本没有找到),那么EXISTS 仍然需要扫描所有块。

定义主键会有什么不同吗?

是的。

PRIMARY KEYEXISTSCOUNT(*) 总是相同的(单索引查找)。

如果没有,EXISTS 将在第一场比赛中停止,而COUNT(*) 将继续到表格的末尾。

更新:

对不起,我之前错了。

似乎SQL ServerCOUNT(*) &gt; 0 优化为EXISTS,所以是的,统计数据是一样的。

DBCC FreeProcCache
CHECKPOINT
DBCC DROPCLEANBUFFERS
SET  STATISTICS IO ON
DECLARE @id UNIQUEIDENTIFIER
SET @id = '7C65EBB1-1242-4084-8BB4-3CC92CA2BE51'
IF      (
        SELECT  COUNT(*)
        FROM    tablewithhugedata
        WHERE   id = @id
        ) > 0
BEGIN
        SELECT CONVERT(BIT, 1)
END
ELSE
BEGIN
        SELECT CONVERT(BIT, 0)
END

DBCC execution completed. If DBCC printed error messages, contact your system administrator.
DBCC execution completed. If DBCC printed error messages, contact your system administrator.
Table 'TableWithHugeData'. Scan count 1, logical reads 1, physical reads 0, read-ahead reads 270, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row(s) affected)

还有一点不同的查询:

DBCC FreeProcCache
CHECKPOINT
DBCC DROPCLEANBUFFERS
SET  STATISTICS IO ON
DECLARE @id UNIQUEIDENTIFIER
SET @id = '7C65EBB1-1242-4084-8BB4-3CC92CA2BE51'
IF EXISTS
        (
        SELECT  1
        FROM    tablewithhugedata
        WHERE   id = @id
        )
BEGIN
        SELECT CONVERT(BIT, 1)
END
ELSE
BEGIN
        SELECT CONVERT(BIT, 0)
END

DBCC FreeProcCache
CHECKPOINT
DBCC DROPCLEANBUFFERS
SET  STATISTICS IO ON
DECLARE @id UNIQUEIDENTIFIER
SET @id = '7C65EBB1-1242-4084-8BB4-3CC92CA2BE51'
IF      (
        SELECT  COUNT(*)
        FROM    tablewithhugedata
        WHERE   id = @id
        ) BETWEEN 1 AND 2
BEGIN
        SELECT CONVERT(BIT, 1)
END
ELSE
BEGIN
        SELECT CONVERT(BIT, 0)
END

DBCC execution completed. If DBCC printed error messages, contact your system administrator.
DBCC execution completed. If DBCC printed error messages, contact your system administrator.
Table 'TableWithHugeData'. Scan count 2, logical reads 266, physical reads 6, read-ahead reads 270, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row(s) affected)

第二个查询需要知道COUNT(*) 的确切值,因此它会读取所有块(266 逻辑读取与1 用于EXISTS / COUNT(*) &gt; 0)。

【讨论】:

"您的 TableWithHugeData 似乎包含一条记录" - 它包含 50000 条记录。 上面的例子没有主键。 当然! COUNT(*) > 0,第一次匹配就足够了! +1 给你。

以上是关于Sql server 2005 :- IF EXISTS 和 COUNT(*) > 0 的 IO 统计信息是不是相同?的主要内容,如果未能解决你的问题,请参考以下文章

在 SQL Server 2005 的查询中与 T-SQL 进行数据比较

SQL Server 2005:“保护”存储过程免受 MS Access 使用的 FMTONLY 模式的影响

深入理解SQL Server 2005 中的 COLUMNS_UPDATED函数

怎样在SQL server 2005 的表中插入图片字段为无效值怎么办

哪里能下载到SQL server 2005?

已安装 SQL Server 2005,安装 SQL Server 2008 时提示需要删除 SQL Server 2005 Express 工具