Leí que las tablas derivadas tienen un mejor rendimiento que las tablas temporales, pero de todos modos muchos desarrolladores de SQL Server prefieren las segundas. ¿Por qué? Debo hacer consultas con datos grandes (millones de registros) y quiero estar seguro de que estoy usando la mejor opción.
CREATE TABLE A(
id BIGINT IDENTITY(1,1) NOT NULL,
field1 INT NOT NULL,
field2 VARCHAR(50) NULL,
);
CREATE TABLE B(
id INT IDENTITY(1,1) NOT NULL,
field1 VARCHAR(10) NULL,
field2 INT NULL
);
INSERT INTO A
(field1,field2)
VALUES
(1,'a'),(2,'b'),(3,'c'),(2,'d'),(5,'e'),
(6,'f'),(7,'g'),(8,'h'),(9,'i'),(2,'j');
INSERT INTO B
(field1,field2)
VALUES
('a',1),('b',2),('c',3),('d',4),('e',5),
('f',6),('g',7),('h',8),('i',9),('j',2),('k',3);
DECLARE @begin INT=0,@end INT=200;
Tablas derivadas
/*derived tables*/
SELECT
C.id,C.field1,C.field2,C.field3
FROM
(
SELECT
A.id,A.field1,A.field2,B.field2 AS field3,
ROW_NUMBER() OVER (ORDER BY A.id) AS iRow
FROM
A INNER JOIN B ON A.field1=B.id
) C
WHERE iRow BETWEEN @begin AND @end;
Mesas temporales
/*temporary tables*/
CREATE TABLE #C (
iRow INT IDENTITY(1,1),
id bigint,
field1 INT,
field2 VARCHAR(50),
field3 INT );
INSERT INTO #C
(id,field1,field2,field3)
SELECT TOP 1000
A.id,A.field1,A.field2,B.field2
FROM
A INNER JOIN B ON A.field1=B.id
ORDER BY
A.id;
SELECT id,field1,field2,field3
FROM #C
WHERE iRow BETWEEN @begin AND @end;
DROP TABLE #C;
SELECT TOP 1000
sin ningunoORDER BY
, eso no es bueno. Creo que debe agregarORDER BY A.id;
para que las dos formas sean equivalentes.Respuestas:
@ user16484 ya lo dirigió a Cuál tiene mejor rendimiento: Tablas derivadas o Tablas temporales en el comentario.
Consulte también Tabla temporal 'vs' Variable de tabla 'vs' CTE. que también cubre tablas derivadas.
Un resumen rápido: las tablas #temp pueden indexarse, pueden tener índices / restricciones ÚNICOS, pueden ser referencias más de una vez en la misma consulta, pueden ser referenciadas (DESDE O UNIRSE) por más de una consulta. Se puede hacer referencia a las tablas derivadas (FROM o JOIN) una vez en una consulta.
En cuanto al rendimiento, extraiga Profiler para SQL: BatchCompleted y RPC: Completed, mire las columnas de lectura, escritura, CPU y duración, y vea lo que hacen algunas ejecuciones de tablas derivadas frente a tablas #temp frente a tablas #temp indexadas cada consulta particular
En general, si lo va a usar más de una vez, la tabla #temp gana. Si te unes a muchas mesas, la tabla #temp probablemente gane. Si solo se une a unas pocas mesas, la mesa derivada tiene una probabilidad razonable de ganar. Benchmark it!
fuente
En general, depende de sus consultas particulares y del tamaño de los resultados temporales.
Para el escenario específico dado, que es la paginación, las tablas temporales son totalmente innecesarias. ¿Por qué querría guardar 1000 filas en una tabla temporal solo para luego devolver las primeras 200? El uso de una tabla 'derivada' o un CTE en este escenario es mucho más eficiente, porque el conjunto de resultados completo no tiene que almacenarse en ningún lado, o en la mayoría de los casos, incluso producirse. Por ejemplo, cuando solicite la primera página de 200 filas, solo las primeras 200 filas deberán recuperarse de las tablas base (suponiendo que los índices existentes puedan admitir el orden de clasificación solicitado en la consulta).
fuente