这是三个读取相同数据,但报告逻辑读取非常不同的简单测试:
设定
下面的脚本创建一个包含100个相同行的测试表,每个表包含一个xml列,其中包含足够的数据以确保其存储在行外。在我的测试数据库中,每行生成的xml的长度为20204字节。
-- Conditional drop
IF OBJECT_ID(N'dbo.XMLTest', N'U') IS NOT NULL
DROP TABLE dbo.XMLTest;
GO
-- Create test table
CREATE TABLE dbo.XMLTest
(
ID integer IDENTITY PRIMARY KEY,
X xml NULL
);
GO
-- Add 100 wide xml rows
DECLARE @X xml;
SET @X =
(
SELECT TOP (100) *
FROM sys.columns AS C
FOR XML
PATH ('row'),
ROOT ('root'),
TYPE
);
INSERT dbo.XMLTest
(X)
SELECT TOP (100)
@X
FROM sys.columns AS C;
-- Flush dirty buffers
CHECKPOINT;
测验
以下三个测试使用以下命令读取xml列:
- 一个简单的
SELECT
声明 - 将xml分配给变量
- 使用
SELECT INTO
创建临时表
-- No row count messages or graphical plan
-- Show I/O statistics
SET NOCOUNT ON;
SET STATISTICS XML OFF;
SET STATISTICS IO ON;
GO
PRINT CHAR(10) + '=== Plain SELECT ===='
DBCC DROPCLEANBUFFERS WITH NO_INFOMSGS;
SELECT XT.X
FROM dbo.XMLTest AS XT;
GO
PRINT CHAR(10) + '=== Assign to a variable ===='
DBCC DROPCLEANBUFFERS WITH NO_INFOMSGS;
DECLARE @X xml;
SELECT
@X = XT.X
FROM dbo.XMLTest AS XT;
GO
PRINT CHAR(10) + '=== SELECT INTO ===='
IF OBJECT_ID(N'tempdb..#T', N'U') IS NOT NULL
DROP TABLE #T;
DBCC DROPCLEANBUFFERS WITH NO_INFOMSGS;
SELECT
XT.X
INTO #T
FROM dbo.XMLTest AS XT
GO
SET STATISTICS IO OFF;
结果
输出为:
===普通SELECT ==== 表“ XMLTest”。扫描计数1,逻辑读取3,物理读取1,预读读取0, lob逻辑读取795,lob物理读取37,lob提前读取796。 ===分配变量==== 表“ XMLTest”。扫描计数1,逻辑读取3,物理读取1,预读读取0, lob逻辑读取为0,lob物理读取为0,lob提前读取为0。 ===选择进入==== 表“ XMLTest”。扫描计数1,逻辑读取3,物理读取1,预读读取0, lob逻辑读取300,lob物理读取37,lob提前读取400。
问题
- 为什么LOB的读法如此不同?
- 是否在每次测试中都读取了完全相同的数据?