Sql server 低统计数据逻辑读取和高探查器读取
我在SSMS中执行了以下程序:Sql server 低统计数据逻辑读取和高探查器读取,sql-server,sql-server-2008,indexing,clustered-index,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 @MyTab
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上有一个聚集索引
每次调用上述过程时,统计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.
但是,当我在探查器中检查同一过程的跟踪时,我发现在读取方面存在巨大差异,甚至在差异方面也存在巨大差异。一次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 DROPCLEANSBUFFERS;DBCC-FREEPROCCACHE在每四次执行之前
SSMS和探查器中的执行计划相同。只有一个聚集索引搜索。成本、行数、执行数、大小这两者都是一样的,那么为什么在读取方面会有如此大的差异呢
编辑:
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
您不应该期望在这两种情况下看到相同的逻辑读取值(
SET STATISTICS IO ON
和SQL Profiler:Batch Completed
),因为它们测量的内容不同:
将仅返回语句的SET STATISTICS IO ON
逻辑读取数
将返回整个批的逻辑读取,其中包括编译生成的逻辑读取(您的批具有DBCC FREEPROCCACHE语句,强制编译,这意味着逻辑读取,因为SQL Server必须读取元数据信息)。此外,如果在SQLServerManagementStudio中激活SQL Profiler:Batch Completed column Reads
,您将看到Query>实际执行计划
列的增加读取数
-- 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分析器
为批处理完成
事件显示另一个结果,即读取
列:
简单的解释是,您正在尝试比较不同的内容。在这两种情况下,您不应该期望看到相同的逻辑读取值(
设置统计IO ON
和SQL Profiler:Batch Completed
),因为它们测量了不同的内容:
将仅返回语句的SET STATISTICS IO ON
逻辑读取数
将返回整个批的逻辑读取,其中包括编译生成的逻辑读取(您的批具有DBCC FREEPROCCACHE语句,强制编译,这意味着逻辑读取,因为SQL Server必须读取元数据信息)。此外,如果在SQLServerManagementStudio中激活SQL Profiler:Batch Completed column Reads
,您将看到Query>实际执行计划
列的增加读取数
-- 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分析器
为批处理完成
事件显示另一个结果,即读取
列:
简单的解释是,您正在尝试比较不同的内容。只有四个,该过程是以前创建的。请为[MyTable]添加定义(CREATE TABLE语句)。是否有使用
UDF
的计算列?否没有计算列。使用的数据类型有int、nvarchar、bit、float和datetime。表中有23列,包括4个FK。@Bogan Sahlen:添加了定义。您在SQL事件探查器中选择了什么事件类<代码>批处理已完成?只有四个,该过程是以前创建的。请为[MyTable]添加定义(CREATE TABLE语句)。是否有使用UDF
的计算列?否没有计算列。使用的数据类型有int、nvarchar、bit、float和datetime。表中有23列,包括4个FK。@Bogan Sahlen:添加了定义。您在SQL事件探查器中选择了什么事件类<代码>批量完成?注意:也许这篇文章能帮助您更好地理解我的(部分)答案:。Quote:“因此,通常情况下,SQL事件探查器报告的逻辑读取与统计IO报告的逻辑读取之和不匹配。但是,SQL事件探查器中报告的读取数应始终等于或大于统计IO值。”@Boddan Sahlan:谢谢你的帮助。注意:也许这篇文章比我的(部分)答案更能帮助你理解:。Quote:“因此,通常情况下,SQL事件探查器报告的逻辑读取与统计IO报告的逻辑读取的总和不匹配。但是,SQL事件探查器中报告的读取数应始终等于或大于统计IO值。”@Boddan Sahlen:感谢您的帮助。