Utilisation de table temporaire dans SQL Server

C'est une question un peu ouverte, mais j'aimerais vraiment entendre les opinions des gens.

J'utilise rarement des tables temporaires explicitement déclarées (soit des tables de variables, soit des tables #tmp normales) car je ne pense pas que cela puisse conduire à un T-SQL plus concis, plus lisible et plus déboguable. Je pense aussi que SQL peut faire un meilleur travail que moi d'utiliser le stockage temporaire quand c'est nécessaire (comme lorsque vous utilisez une table dérivée dans une requête).

La seule exception est lorsque la database n'est pas une database relationnelle typique mais un schéma en écanvas ou en flocon de neige. Je comprends qu'il est préférable d'appliquer d'abord les filters à la table des faits, puis d'utiliser la table temporaire résultante pour get les valeurs de vos dimensions.

Est-ce l'opinion commune ou quelqu'un a-t-il une opinion opposée?

Les tables temporaires sont particulièrement utiles pour un process de traitement par lots complexe, tel qu'un rapport ou un travail ETL. Généralement, vous vous attendez à les utiliser assez rarement dans une application transactionnelle.

Si vous faites une requête complexe avec une jointure impliquant plusieurs tables volumineuses (peut-être pour un rapport), l'optimiseur de requêtes peut ne pas être en mesure d'optimiser ceci en un coup, les tables temporaires deviennent alors gagnantes – elles décomposent la requête en une série des plus simples qui donnent less de possibilités à l'optimiseur de requêtes de bousiller le plan. Parfois, vous avez une opération qui ne peut pas être effectuée dans une seule instruction SQL, donc plusieurs étapes de traitement sont nécessaires pour effectuer le travail. Encore une fois, nous parlons ici de manipulations plus complexes.

Vous pouvez également créer une table temporaire pour un résultat intermédiaire, puis indexer la table, éventuellement en y ajoutant un index clusterisé pour optimiser une requête ultérieure. Cela peut également être un moyen rapide et efficace d'optimiser une requête de rapport sur un système dans lequel vous n'êtes pas autorisé à append des index au schéma de database. SELECT INTO est utile pour ce type d'opération car il est minime (et donc rapide) et ne nécessite pas d'aligner les colonnes d'un select et d'un insert.

D'autres raisons peuvent inclure l'extraction de données à partir de champs XML à l'aide de requêtes CROSS APPLY et xpath. Généralement, il est beaucoup plus efficace d'extraire ceci dans une table temporaire, puis de travailler sur la table temporaire. Ils sont également beaucoup plus rapides que les CTE pour certaines tâches car ils matérialisent les résultats de la requête plutôt que de réévaluer la requête.

Une chose à noter est que les tables temporaires sont exactement la même structure que celle utilisée par le moteur de search pour stocker les résultats des jointures intermédiaires. Il n'y a donc aucune pénalité de performance à les utiliser. Les tables temporaires permettent également des tâches multiphases utilisant des opérations d'set et rendent les sliders presque (pas tout à fait presque) inutiles dans le code T-SQL.

L'odeur du code est une surestimation, mais si je voyais beaucoup d'opérations simples impliquant des tables temporaires, je me requestrais ce qui se passait.

Cela dépend vraiment de ce que vous faites. J'essaie généralement de les éviter, mais parfois vous devez faire quelque chose de compliqué qui prend plusieurs étapes. Généralement, cela va bien au-delà du simple choix de la table. Comme tout le rest, c'est un outil que vous devez savoir quand l'utiliser.

Je suis d'accord avec vous pour dire que je laisse normalement le db gérer les choses en coulisses, mais il y a des moments où l'optimization est désactivée et il faut y aller et le faire à la main.

Je vois les arrays temporaires comme une sorte d'odeur de code SQL, à utiliser uniquement en dernier recours. Si vous devez mettre en cache des données avant d'get un jeu de résultats final, cela indique généralement une mauvaise design de database.

Les tables temporaires ont certainement des utilisations appropriées, elles ne sont pas une odeur de code si elles sont utilisées correctement. L'une des bonnes choses à leur sujet est qu'ils vivent dans tempdb, qui est généralement défini sur le model de récupération simple. Cela signifie que si vous utilisez des tables temporaires pour ce qu'elles sont bonnes (principalement des opérations en masse), vous générez une quantité minimale de journaux par rapport à ce que la même opération ferait sur des tables dans votre production db, ce qui est probablement dans le model de récupération complète.

Si, comme le suggère une autre affiche, votre production db est sur un bon matériel, mais que votre tempdb ne l'est pas, requestz à votre DBA de le déplacer. SQL Server lui-même utilise un peu tempdb pour traiter vos requêtes, il est donc important pour tempdb d'avoir une maison haute performance.

Les variables de table sont une créature différente entièrement. Ils ne vivent que dans la memory. Un bon usage pour eux est si vous avez une fonction que vous devez appeler pour chaque ligne de votre requête avec CROSS APPLY. Si cette fonction est coûteuse, mais que le nombre de résultats différents que vous pouvez get est faible, vous pouvez get des performances significativement plus élevées en calculant les résultats de tous les appels possibles (ou tous les appels possibles pour votre jeu de données). variable de table, puis de se joindre à cette variable de table au lieu d'utiliser CROSS APPLY.

Moi aussi, j'évite les tables temporaires. Je crois comprendre que les tables temporaires sur MS SQL Server sont toujours dans le groupe de files de la database master. Cela signifie que, bien que vos tables d'applications de production soient probablement configurées sur un système RAID hautes performances onéreux, vos tables temporaires sont situées partout où MS SQL Server a été installé, probablement sur votre lecteur C: dans le directory Program Files.

Cela est également utile lorsque vous avez un set de données qui doit être extrait une fois et utilisé à plusieurs resockets dans les instructions suivantes.

Rend ces process par lots plus lisibles (parfois c'est plus important que la performance).