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;
SELECT TOP 1000
sans aucunORDER BY
, ce n'est pas bon. Je pense que vous devez ajouterORDER BY A.id;
pour que les deux façons soient équivalentes.Réponses:
@ 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!
la source
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).
la source