Há vantagens em usar tabelas temporárias sobre tabelas derivadas no SQL Server?

8

Eu li que as tabelas derivadas têm melhor desempenho do que as tabelas temporárias, mas de qualquer maneira muitos desenvolvedores do SQL Server preferem as segundas. Por quê? Devo fazer consultas com grandes dados (milhões de registros) e quero ter certeza de que estou usando a melhor opção.

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;

Tabelas 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;

Tabelas temporárias

/*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;
norgematos
fonte
11
Você tem um SELECT TOP 1000sem ORDER BY, isso não é bom. Eu acho que você precisa adicionar ORDER BY A.id;as duas maneiras de ser equivalente.
ypercubeᵀᴹ
É apenas uma amostra. O objetivo é mostrar o tópico principal da minha pergunta.
Norgematos

Respostas:

6

@ user16484 já direcionou você para Qual deles tem melhor desempenho: Tabelas Derivadas ou Tabelas Temporárias no comentário.

Consulte também Temp Table 'vs' Table Variable 'vs' CTE. que também abrange tabelas derivadas.

Um resumo rápido: #temp tables podem ser indexadas, podem ter índices / restrições UNIQUE, podem ser referências mais de uma vez na mesma consulta, podem ser referenciadas (FROM ou JOIN) por mais de uma consulta. As tabelas derivadas podem ser referenciadas (FROM ou JOIN) uma vez em uma consulta.

Em termos de desempenho, retire o Profiler for SQL: BatchCompleted e RPC: Concluído, observe as colunas Leitura, Gravação, CPU e Duração e veja o que algumas execuções de tabelas derivadas versus #temp tables e #temp indexadas fazem para cada consulta em particular.

Em geral - se você for usá-lo mais de uma vez, a tabela #temp vence. Se você estiver ingressando em muitas tabelas, a #temp table provavelmente vence. Se você ingressar em apenas algumas mesas, a tabela derivada tem uma chance razoável de ganhar. Benchmark it!

Senhas anti-fracas
fonte
6

Em geral, isso depende de suas consultas específicas e do tamanho dos resultados temporários.

Para o cenário específico fornecido, que é a paginação, as tabelas temporárias são totalmente desnecessárias. Por que você deseja salvar 1000 linhas em uma tabela temporária apenas para retornar os primeiros 200? Usar uma tabela 'derivada' ou um CTE nesse cenário é muito mais eficiente, porque o conjunto de resultados completo não precisa ser armazenado em nenhum lugar ou, na maioria dos casos, até produzido. Por exemplo, ao solicitar a 1ª página de 200 linhas, apenas as 200 primeiras terão que ser recuperadas das tabelas base (assumindo que os índices existentes possam suportar a ordem de classificação solicitada na consulta).

Vlad G.
fonte
11
+1, embora eu acrescentasse que o uso de tabelas derivadas também permite que o Query Optimizer lide com as duas consultas ao mesmo tempo. Isso pode ser bom ou, às vezes, ruim, novamente "dependendo da consulta específica". É por isso que é sempre bom testar ambos (em dados reais, não dados de amostra) em vez de adivinhar :-).
Solomon Rutzky