Dans SQL Server 2005, nous pouvons créer des tables temporaires de deux manières:
declare @tmp table (Col1 int, Col2 int);
ou
create table #tmp (Col1 int, Col2 int);
Quelles sont les différences entre ces deux? J'ai lu des opinions contradictoires sur si @tmp utilise toujours tempdb, ou si tout se passe en mémoire.
Dans quels scénarios l'un surpasse-t-il l'autre?
sql-server
temp-tables
table-variable
Eric Z Beard
la source
la source
Réponses:
Il existe quelques différences entre les tables temporaires (#tmp) et les variables de table (@tmp), bien que l'utilisation de tempdb n'en soit pas une, comme indiqué dans le lien MSDN ci-dessous.
En règle générale, pour les volumes de données petits à moyens et les scénarios d'utilisation simples, vous devez utiliser des variables de table. (Il s'agit d'une directive trop large avec bien sûr de nombreuses exceptions - voir ci-dessous et les articles suivants.)
Quelques points à considérer lors du choix entre eux:
Les tables temporaires sont de vraies tables, vous pouvez donc faire des choses comme CRÉER DES INDEX, etc. Si vous avez de grandes quantités de données pour lesquelles l'accès par index sera plus rapide, les tables temporaires sont une bonne option.
Les variables de table peuvent avoir des index à l'aide de contraintes PRIMARY KEY ou UNIQUE. (Si vous voulez un index non unique, incluez simplement la colonne de clé primaire comme dernière colonne dans la contrainte unique. Si vous n'avez pas de colonne unique, vous pouvez utiliser une colonne d'identité.) SQL 2014 a aussi des index non uniques .
Les variables de table ne participent pas aux transactions et les
SELECT
s le sont implicitementNOLOCK
. Le comportement de la transaction peut être très utile, par exemple si vous souhaitez faire un ROLLBACK à mi-chemin d'une procédure, alors les variables de table remplies pendant cette transaction seront toujours remplies!Les tables temporaires peuvent entraîner la recompilation des procédures stockées, peut-être souvent. Les variables de table ne le seront pas.
Vous pouvez créer une table temporaire à l'aide de SELECT INTO, qui peut être plus rapide à écrire (idéal pour les requêtes ad hoc) et peut vous permettre de faire face aux changements de types de données au fil du temps, car vous n'avez pas besoin de définir la structure de votre table temporaire à l'avance.
Vous pouvez renvoyer des variables de table à partir de fonctions, ce qui vous permet d'encapsuler et de réutiliser la logique beaucoup plus facilement (par exemple, rendre une fonction pour diviser une chaîne en une table de valeurs sur un délimiteur arbitraire).
L'utilisation de variables de table dans des fonctions définies par l'utilisateur permet d'utiliser ces fonctions plus largement (voir la documentation CREATE FUNCTION pour plus de détails). Si vous écrivez une fonction, vous devez utiliser des variables de table sur des tables temporaires, sauf indication contraire impérative.
Les variables de table et les tables temporaires sont stockées dans tempdb. Mais les variables de table (depuis 2005) utilisent par défaut le classement de la base de données actuelle par rapport aux tables temporaires qui prennent le classement par défaut de tempdb ( ref ). Cela signifie que vous devez être conscient des problèmes de classement si vous utilisez des tables temporaires et que votre classement db est différent de celui de tempdb, ce qui pose des problèmes si vous souhaitez comparer les données de la table temporaire avec les données de votre base de données.
Les tables temporaires globales (## tmp) sont un autre type de table temporaire disponible pour toutes les sessions et tous les utilisateurs.
Quelques lectures supplémentaires:
La grande réponse de Martin Smith sur dba.stackexchange.com
FAQ MSDN sur la différence entre les deux: https://support.microsoft.com/en-gb/kb/305977
Article de blog MDSN: https://docs.microsoft.com/archive/blogs/sqlserverstorageengine/tempdb-table-variable-vs-local-temporary-table
Article: https://searchsqlserver.techtarget.com/tip/Temporary-tables-in-SQL-Server-vs-table-variables
Comportements inattendus et implications en termes de performances des tables temporaires et des variables temporaires: Paul White sur SQLblog.com
la source
Il suffit de regarder l'affirmation dans la réponse acceptée selon laquelle les variables de table ne participent pas à la journalisation.
Il semble généralement faux qu'il existe une différence dans la quantité de journalisation (au moins pour les opérations
insert
/update
/delete
sur la table elle-même, bien que j'ai depuis constaté qu'il y a une petite différence à cet égard pour les objets temporaires mis en cache dans les procédures stockées en raison de la table système supplémentaire mises à jour).J'ai examiné le comportement de journalisation par rapport à a
@table_variable
et à une#temp
table pour les opérations suivantes.Les enregistrements du journal des transactions étaient presque identiques pour toutes les opérations.
La version de la variable de table contient en fait quelques entrées de journal supplémentaires, car elle obtient une entrée ajoutée (et ultérieurement supprimée de) la
sys.syssingleobjrefs
table de base, mais dans l'ensemble, quelques octets de moins étaient consignés uniquement, car le nom interne des variables de table consomme 236 octets de moins que pour les#temp
tables. (118nvarchar
caractères de moins ).Script complet à reproduire (meilleure exécution sur une instance démarrée en mode mono-utilisateur et en
sqlcmd
mode utilisation )Résultats
la source
INSERT ... SELECT
n'étaient pas enregistrées de façon minimale et vous ne pouvez pas utiliser deSELECT INTO ...
variable de table.Pour les petites tables (moins de 1 000 lignes), utilisez une variable temporaire, sinon utilisez une table temporaire.
la source
@wcm - en fait pour choisir la variable de table n'est pas seulement Ram - elle peut être partiellement stockée sur le disque.
Une table temporaire peut avoir des index, tandis qu'une variable de table ne peut avoir qu'un index primaire. Si la vitesse est un problème, les variables de la table peuvent être plus rapides, mais évidemment s'il y a beaucoup d'enregistrements, ou la nécessité de rechercher la table temporaire d'un index clusterisé, alors une table temporaire serait mieux.
Bon article de fond
la source
Table temporaire: Une table temporaire est facile à créer et à sauvegarder des données.
Variable de table: Mais la variable de table implique l'effort lorsque nous créons habituellement les tables normales.
Table temporaire: le résultat de la table temporaire peut être utilisé par plusieurs utilisateurs.
Variable de table: Mais la variable de table ne peut être utilisée que par l'utilisateur actuel.
Table temporaire: La table temporaire sera stockée dans la tempdb. Cela fera du trafic réseau. Lorsque nous avons de grandes données dans la table temporaire, elles doivent fonctionner dans la base de données. Un problème de performances existera.
Variable de table: Mais une variable de table stockera dans la mémoire physique pour certaines des données, puis plus tard lorsque la taille augmentera, elle sera déplacée vers tempdb.
Table temporaire: La table temporaire peut effectuer toutes les opérations DDL. Il permet de créer des index, de les supprimer, de les modifier, etc.,
Variable de table: alors que la variable de table ne permet pas d'effectuer les opérations DDL. Mais la variable de table nous permet de créer l'index cluster uniquement.
Table temporaire: La table temporaire peut être utilisée pour la session en cours ou globale. Pour qu'une session multi-utilisateurs puisse utiliser les résultats du tableau.
Variable de table: Mais la variable de table peut être utilisée jusqu'à ce programme. (Procédure stockée)
Table temporaire: la variable temporaire ne peut pas utiliser les transactions. Lorsque nous effectuons les opérations DML avec la table temporaire, il peut être annulé ou validé les transactions.
Variable de table: Mais nous ne pouvons pas le faire pour la variable de table.
Table temporaire: les fonctions ne peuvent pas utiliser la variable temporaire. De plus, nous ne pouvons pas faire l'opération DML dans les fonctions.
Variable de table: Mais la fonction nous permet d'utiliser la variable de table. Mais en utilisant la variable de table, nous pouvons le faire.
Table temporaire: La procédure stockée effectuera la recompilation (ne peut pas utiliser le même plan d'exécution) lorsque nous utilisons la variable temporaire pour chaque appel de sous-séquence.
Variable de table: alors que la variable de table ne fera pas comme ça.
la source
Pour tous ceux qui croient au mythe que les variables temporaires ne sont qu'en mémoire
Premièrement, la variable de table N'EST PAS nécessairement résidente en mémoire. Sous la pression de la mémoire, les pages appartenant à une variable de table peuvent être déplacées vers tempdb.
Lisez l'article ici: Variable TempDB :: Table vs table temporaire locale
la source
L'autre différence principale est que les variables de table n'ont pas de statistiques de colonne, contrairement aux tables temporaires. Cela signifie que l'optimiseur de requêtes ne sait pas combien de lignes se trouvent dans la variable de table (il en suppose 1), ce qui peut conduire à des plans hautement non optimaux générés si la variable de table a en fait un grand nombre de lignes.
la source
rows
colonne danssys.partitions
est conservée pour les variables de table afin qu'elle sache réellement combien de lignes se trouvent dans la table. Cela peut être vu en utilisantOPTION (RECOMPILE)
. Mais le manque de statistiques de colonne signifie qu'il ne peut pas estimer les prédicats de colonne spécifiques.Citation tirée de; Internes et dépannage professionnels de SQL Server 2012
LES VARIABLES DES TABLEAUX NE SONT PAS CRÉÉES EN MÉMOIRE
Il existe une idée fausse commune selon laquelle les variables de table sont des structures en mémoire et, en tant que telles, fonctionneront plus rapidement que les tables temporaires . Merci à un DMV appelé sys. dm _ db _ session _ space _ usage, qui montre l'utilisation de tempdb par session, vous pouvez prouver que ce n'est pas le cas . Après avoir redémarré SQL Server pour effacer la DMV, exécutez le script suivant pour confirmer que votre identifiant de session _ renvoie 0 pour l'utilisateur _ objets _ alloc _ page _ nombre:
Vous pouvez maintenant vérifier l'espace utilisé par une table temporaire en exécutant le script suivant pour créer une table temporaire avec une colonne et la remplir avec une ligne:
Les résultats sur mon serveur indiquent que la table a été allouée une page dans tempdb. Exécutez maintenant le même script mais utilisez cette fois une variable de table:
Lequel utiliser?
la source
Une autre différence:
Une table var n'est accessible qu'à partir des instructions de la procédure qui la crée, pas à partir d'autres procédures appelées par cette procédure ou du SQL dynamique imbriqué (via exec ou sp_executesql).
La portée d'une table temporaire, en revanche, inclut du code dans des procédures appelées et du SQL dynamique imbriqué.
Si la table créée par votre procédure doit être accessible à partir d'autres procédures appelées ou SQL dynamique, vous devez utiliser une table temporaire. Cela peut être très pratique dans des situations complexes.
la source
Les différences entre
Temporary Tables (##temp/#temp)
etTable Variables (@table)
sont les suivantes:Table variable (@table)
est créé dans lememory
. Alors que, unTemporary table (##temp/#temp)
est créé dans letempdb database
. Cependant, s'il y a une pression mémoire, les pages appartenant à une variable de table peuvent être poussées vers tempdb.Table variables
ne peut pas être impliqué danstransactions, logging or locking
. Cela fait@table faster then #temp
. La table variable est donc plus rapide que la table temporaire.Temporary table
permet des modifications de schéma contrairementTable variables
.Temporary tables
sont visibles dans la routine créée et également dans les routines enfants. Alors que les variables de table ne sont visibles que dans la routine créée.Temporary tables
sont autorisésCREATE INDEXes
alors que,Table variables
ne sont pas autorisés à laCREATE INDEX
place, ils peuvent avoir un index en utilisantPrimary Key or Unique Constraint
.la source
Considérez également que vous pouvez souvent remplacer les deux par des tables dérivées qui peuvent également être plus rapides. Comme pour tout réglage des performances, cependant, seuls les tests réels par rapport à vos données réelles peuvent vous indiquer la meilleure approche pour votre requête particulière.
la source
Cela me surprend que personne n'ait mentionné la principale différence entre ces deux éléments: la table temporaire prend en charge l' insertion parallèle, contrairement à la variable de table. Vous devriez pouvoir voir la différence par rapport au plan d'exécution. Et voici la vidéo des ateliers SQL sur le canal 9 .
Cela explique également pourquoi vous devez utiliser une variable temporaire pour les petites tables, sinon utilisez une table temporaire, comme SQLMenace l'a déjà répondu .
la source