Dada la siguiente tabla de montón con 400 filas numeradas del 1 al 400:
DROP TABLE IF EXISTS dbo.N;
GO
SELECT
SV.number
INTO dbo.N
FROM master.dbo.spt_values AS SV
WHERE
SV.[type] = N'P'
AND SV.number BETWEEN 1 AND 400;
y la siguiente configuración:
SET NOCOUNT ON;
SET STATISTICS IO, TIME OFF;
SET STATISTICS XML OFF;
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
La siguiente SELECT
declaración se completa en unos 6 segundos ( demostración , plan ):
DECLARE @n integer = 400;
SELECT
c = COUNT_BIG(*)
FROM dbo.N AS N
CROSS JOIN dbo.N AS N2
CROSS JOIN dbo.N AS N3
WHERE
N.number <= @n
AND N2.number <= @n
AND N3.number <= @n
OPTION
(OPTIMIZE FOR (@n = 1));
Nota: @La OPTIMIZE FOR
cláusula es solo para producir una reproducción de tamaño razonable que capture los detalles esenciales del problema real, incluida una desestimación de la cardinalidad que puede surgir por una variedad de razones.
Cuando la salida de una fila se escribe en una tabla, demora 19 segundos ( demostración , plan ):
DECLARE @T table (c bigint NOT NULL);
DECLARE @n integer = 400;
INSERT @T
(c)
SELECT
c = COUNT_BIG(*)
FROM dbo.N AS N
CROSS JOIN dbo.N AS N2
CROSS JOIN dbo.N AS N3
WHERE
N.number <= @n
AND N2.number <= @n
AND N3.number <= @n
OPTION
(OPTIMIZE FOR (@n = 1));
Los planes de ejecución aparecen idénticos aparte de la inserción de una fila.
Todo el tiempo extra parece ser consumido por el uso de la CPU.
¿Por qué la INSERT
declaración es mucho más lenta?
fuente