2010-10-29 53 views
2

EDIT: -SQL Server 2005中: - 兩個IF EXISTS和COUNT(*)> 0同一個IO的統計數據?

隨着以下兩個用於產生PK上Id列EXISTS和COUNT(*)> 0

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 

EXISTS

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統計數據: -

Table'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統計對於計數()> 0 **: -

表 'TableWithHugeData'。掃描計數1,邏輯讀取6,物理讀取1,預讀270,lob邏輯讀取0,lob物理讀取0,lob預讀讀取0.

如您所見,EXISTS和COUNT的IO統計(*)> 0是相同的。我認爲EXISTS會更快,並會執行更少的讀取。我在這裏錯過了什麼嗎?定義一個主鍵會有什麼區別?

+0

沒有索引,如果沒有價值沒有找到或者在表的末尾...... – 2010-10-29 10:29:03

+0

我很抱歉。我只是從表格中選擇了一個值,並嘗試在表格中找到相同的值。它在桌上。我應該提出一個查詢來獲取簡單的運行。 – 2010-10-29 10:30:20

回答

3

如您所見,EXISTS和COUNT(*)> 0的IO統計數據是相同的。我認爲EXISTS會更快,並會執行更少的讀取。我在這裏錯過了什麼嗎?

SQL Server以塊爲單位讀取數據。

如果你正在尋找的記錄恰好是最後的塊(或沒有發現在所有),那麼EXISTS仍然要掃描所有塊。

會定義主鍵將有什麼區別?

是的。

隨着PRIMARY KEY,EXISTSCOUNT(*)將始終是相同的(單索引尋找)。

沒有人,EXISTS將停止第一場比賽,而COUNT(*)將繼續到表的末尾。

更新:

對不起,我有錯在先。

似乎SQL Server優化COUNT(*) > 0EXISTS,所以是的,統計數據是相同的。

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邏輯讀取與1EXISTS/COUNT(*) > 0)。

+0

「你TableWithHugeData似乎由一個記錄」 - 它由50000條記錄。 – 2010-10-29 10:31:06

+0

@ydobonmai:當然,首先錯過了這一點。 – Quassnoi 2010-10-29 10:32:47

+0

上面的例子是沒有主鍵。 – 2010-10-29 10:35:48

相關問題