Y a-t-il des avantages à utiliser des tables temporaires par rapport aux tables dérivées dans SQL Server?


8

J'ai lu que les tables dérivées ont de meilleures performances que les tables temporaires, mais de toute façon de nombreux développeurs SQL Server préfèrent les seconds. Pourquoi? Je dois faire des requêtes avec des données volumineuses (millions d'enregistrements) et je veux être sûr d'utiliser le meilleur choix.

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;

Tables dérivées

/*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;

Tables temporaires

/*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;

1
Vous en avez SELECT TOP 1000sans aucun ORDER BY, ce n'est pas bon. Je pense que vous devez ajouter ORDER BY A.id;pour que les deux façons soient équivalentes.
ypercubeᵀᴹ

Ce n'est qu'un échantillon. Le but est de montrer le sujet principal de ma question.
norgematos

Réponses:


6

@ user16484 vous a déjà dirigé vers laquelle ont de meilleures performances: Tables dérivées ou Tables temporaires dans le commentaire.

Voir également Temp Table 'vs' Table Variable 'vs' CTE. qui couvre également les tableaux dérivés.

Un résumé rapide: les tables #temp peuvent être indexées, peuvent avoir des index / contraintes UNIQUES, peuvent être des références plus d'une fois dans la même requête, peuvent être référencées (FROM ou JOIN) par plusieurs requêtes. Les tables dérivées peuvent être référencées (FROM ou JOIN) une fois dans une requête.

En termes de performances, retirez le Générateur de profils pour SQL: BatchCompleted et RPC: Terminé, regardez les colonnes Lecture, Écriture, CPU et Durée, et voyez ce que quelques exécutions de tables dérivées vs #temp tables vs indexées #temp tables font pour chaque requête particulière.

En général - si vous comptez l'utiliser plusieurs fois, la table #temp l'emporte. Si vous rejoignez un grand nombre de tables, la table #temp gagne probablement. Si vous rejoignez seulement quelques tables, la table dérivée a une chance raisonnable de gagner. Benchmark it!


6

En général, cela dépend de vos requêtes particulières et de la taille des résultats temporaires.

Pour le scénario spécifique donné, qui est la pagination, les tables temporaires sont totalement inutiles. Pourquoi voudriez-vous enregistrer 1000 lignes dans une table temporaire pour ensuite retourner le 1er 200? L'utilisation d'une table «dérivée» ou d'un CTE dans ce scénario est beaucoup plus efficace, car l'ensemble de résultats complet n'a pas besoin d'être stocké n'importe où, ou dans la plupart des cas, même produit. Par exemple, lors de la demande de la 1ère page de 200 lignes, seules les 200 premières lignes devront être extraites des tables de base (en supposant que les index existants peuvent prendre en charge l'ordre de tri demandé dans la requête).


1
+1, bien que j'ajouterais que l'utilisation de tables dérivées permet également à l'Optimiseur de requête de traiter les deux requêtes en même temps. Cela peut être bon ou parfois mauvais, encore une fois "en fonction de la requête particulière". C'est pourquoi il est toujours bon de tester les deux (sur des données réelles, pas des données d'échantillon) plutôt que de deviner :-).
Solomon Rutzky
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.