低统计逻辑读取和高分析器读取

时间:2013-08-17 17:59:57

标签: sql-server sql-server-2008 indexing clustered-index

我在SSMS中执行了以下程序:

CREATE Procedure [dbo].[MyTableLoadByPK]  
(  
    @MyTableID int  
)  
AS  
BEGIN  
    SET NOCOUNT ON  
    SELECT  
    *  
    FROM [MyTable]  
    WHERE  
    del = 0 AND MyTableID = @MyTableID 
END  

exec MyTableLoadByPK @MyTableID=1001

MyTable 有40000条记录, MyTableID 上有聚集索引。

每次调用上述程序时,STATISTICS IO都相同逻辑读取2,物理读取2

Table 'MyTable'. Scan count 0, logical reads 2, physical reads 2, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

但是当我在Profiler中检查跟踪相同的程序时,我发现读取的差异很大,甚至差异也不同。一次248次,三次228次。

以下是从跟踪中读取的内容:

TextData                                    CPU  Reads   Writes    Duration

exec MyTableLoadByPK @MyTableID=1001        0    228     0         223
exec MyTableLoadByPK @MyTableID=1001        0    228     0         230
exec MyTableLoadByPK @MyTableID=1001        0    248     0         751
exec MyTableLoadByPK @MyTableID=1001        0    228     0         360

注意:我已经执行了 DBCC DROPCLEANBUFFERS; DBCC FREEPROCCACHE; 在每次执行四次之前。

SSMS和Profiler中的执行计划相同。只有一个Clustered Index Seek。成本,行,执行,大小在两者中都是相同的,那么为什么读取有这么大的差异。

修改

MyTable create语句如下:

CREATE TABLE [dbo].[MyTable](
    [MyTableID] [int] IDENTITY(1,1) NOT NULL,
    [na] [nvarchar](255) NOT NULL,
    [conID] [int] NOT NULL,
    [coID] [int] NOT NULL,
    [sID] [int] NOT NULL,
    [coID_O] [int] NOT NULL,
    [sID_O] [int] NOT NULL,
    [ufmts] [bit] NOT NULL,
    [Lte] [float] NOT NULL,
    [Late] [float] NOT NULL,
    [tz] [nvarchar](20) NOT NULL,
    [dm] [int] NOT NULL,
    [ca] [nvarchar](20) NOT NULL,
    [Tt] [nvarchar](50) NOT NULL,
    [Ct] [nvarchar](2048) NOT NULL,
    [pub] [bit] NOT NULL,
    [do] [int] NOT NULL,
    [cuID] [int] NOT NULL,
    [ia] [nvarchar](50) NOT NULL,
    [con] [datetime] NOT NULL,
    [uon] [datetime] NOT NULL,
    [upc] [int] NOT NULL,
    [del] [bit] NOT NULL,
 CONSTRAINT [PK_MyTable] PRIMARY KEY CLUSTERED 
(
    [MyTableID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 80) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[MyTable]  WITH CHECK ADD  CONSTRAINT [FK_MyTable_con] FOREIGN KEY([conID])
REFERENCES [dbo].[MYcon] ([conID])
GO

ALTER TABLE [dbo].[MyTable] CHECK CONSTRAINT [FK_MyTable_Mycon]
GO

ALTER TABLE [dbo].[MyTable]  WITH CHECK ADD  CONSTRAINT [FK_MyTable_Myco] FOREIGN KEY([coID])
REFERENCES [dbo].[Myco] ([coID])
GO

ALTER TABLE [dbo].[MyTable] CHECK CONSTRAINT [FK_MyTable_Myco]
GO

ALTER TABLE [dbo].[MyTable]  WITH CHECK ADD  CONSTRAINT [FK_MyTable_Mys] FOREIGN KEY([sID])
REFERENCES [dbo].[Mys] ([sID])
GO

ALTER TABLE [dbo].[MyTable] CHECK CONSTRAINT [FK_MyTable_Mys]
GO

ALTER TABLE [dbo].[MyTable] ADD  CONSTRAINT [DF_MyTable_upc]  DEFAULT ((0)) FOR [upc]
GO

1 个答案:

答案 0 :(得分:4)

在这两种情况下(SET STATISTICS IO ONSQL Profiler:Batch Completed),你不应该期望看到相同的逻辑读取值,因为它们有不同的东西:

  • SET STATISTICS IO ON仅返回logical reads语句[s],
  • SQL Profiler:Batch Completed column Reads将返回整批的逻辑读取,包括此处通过编译生成的逻辑读取(您的批处理具有强制编译的DBCC FREEPROCCACHE语句,这意味着逻辑读取因为SQL Server具有阅读元数据信息)。此外,如果在SQL Server Management Studio中激活Query > Actual execution plan,您会看到Reads列的增加。

例如,当我在SSMS中运行这两批时

-- Without Query > Actual Execution Plan
DBCC DROPCLEANBUFFERS; 
DBCC FREEPROCCACHE;
exec MyTableLoadByPK @MyTableID=1001
GO
-- With Query > Actual Execution Plan
DBCC DROPCLEANBUFFERS; 
DBCC FREEPROCCACHE;
exec MyTableLoadByPK @MyTableID=1001
GO

SET STATISTICS IO ON的输出为 0逻辑读取

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 'MyTable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
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 'MyTable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

SQL Profiler显示Batch completed个事件的另一个结果显示在Reads列中: enter image description here

<强> TLDR: 简单的解释是你试图比较不同的东西。