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

Pra*_*ash 1 sql-server indexing clustered-index sql-server-2008

我在 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
Run Code Online (Sandbox Code Playgroud)

MyTable有 40000 条记录,并且MyTableID上有一个聚集索引。

每次我调用上述过程逻辑读取 2,物理读取 2 时,统计 IO 都是相同的:

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.
Run Code Online (Sandbox Code Playgroud)

但是当我在 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
Run Code Online (Sandbox Code Playgroud)

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

SSMS 和 Profiler 中的执行计划是相同的。只有一个聚集索引搜索。成本、行、执行、大小在两者中一切都相同,那么为什么读取有如此大的差异。

编辑:

MyTable 创建语句如下:

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
Run Code Online (Sandbox Code Playgroud)

Bog*_*ean 5

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

  • SET STATISTICS IO ON将只返回logical reads语句[s],
  • SQL Profiler:Batch Completed column Reads将返回整个批处理的逻辑读取,包括此处由编译生成的逻辑读取(您的批处理具有强制编译的 DBCC FREEPROCCACHE 语句,这意味着逻辑读取,因为 SQL Server 必须读取元数据信息)。此外,如果您Query > Actual execution plan在 SQL Server Management Studio 中激活,您将看到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
Run Code Online (Sandbox Code Playgroud)

的输出SET STATISTICS IO ON0 个逻辑读取

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.
Run Code Online (Sandbox Code Playgroud)

但在列中SQL Profiler显示Batch completed事件的另一个结果Reads在此处输入图片说明

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