Aquí hay tres pruebas simples que leen los mismos datos, pero informan lecturas lógicas muy diferentes:
Preparar
El siguiente script crea una tabla de prueba con 100 filas idénticas, cada una de las cuales contiene una columna xml con datos suficientes para garantizar que se almacene fuera de la fila. En mi base de datos de prueba, la longitud del xml generado es de 20,204 bytes por cada fila.
-- 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;
Pruebas
Las siguientes tres pruebas leen la columna xml con:
- Una
SELECT
declaración simple - Asignando el xml a una variable
- Utilizando
SELECT INTO
para crear una tabla temporal
-- 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;
Resultados
El resultado es:
=== SELECCIONAR llano ==== Tabla 'XMLTest'. Cuenta de escaneo 1, lecturas lógicas 3, lecturas físicas 1, lecturas anticipadas 0, las lecturas lógicas lob 795, las lecturas físicas lob 37, las lecturas anticipadas lob 796. === Asignar a una variable ==== Tabla 'XMLTest'. Cuenta de escaneo 1, lecturas lógicas 3, lecturas físicas 1, lecturas anticipadas 0, lecturas lógicas lob 0, lecturas físicas lob 0, lecturas anticipadas lob 0. === SELECCIONAR EN ==== Tabla 'XMLTest'. Cuenta de escaneo 1, lecturas lógicas 3, lecturas físicas 1, lecturas anticipadas 0, lecturas lógicas lob 300, lecturas físicas lob 37, lecturas anticipadas lob 400.
Preguntas
- ¿Por qué las lecturas de LOB son tan diferentes?
- ¿Seguramente se leyeron exactamente los mismos datos en cada prueba?