Ainsi, récemment, un administrateur de base de données essaie de nous dire que nous ne pouvons pas utiliser la syntaxe de
SELECT X, Y, Z
INTO #MyTable
FROM YourTable
Pour créer des tables temporaires dans notre environnement, car cette syntaxe provoque un verrouillage sur TempDB pour la durée de l’exécution de la procédure stockée. Maintenant, j'ai trouvé un certain nombre d'éléments expliquant le fonctionnement des tables temporaires, la portée de l'exécution, le nettoyage, etc. Mais pour ma vie, je ne vois rien au blocage en raison de leur utilisation.
Nous essayons de trouver des preuves que nous ne devrions pas avoir à passer par CREATE TABLE #MyTable ... pour toutes nos tables temporaires, mais aucune des deux parties ne peut en trouver. Je recherche toute idée SO que les gens ont.
Information additionnelle
Travaille actuellement avec SQL Server 2005, et bientôt SQL Server 2008 (éditions Enterprise)
Ce conseil flotte depuis depuis longtemps :
Goulots d'étranglement dans SQL Server 6.5
De nombreuses personnes utilisent une requête SELECT ... INTO créer une table temporaire, quelque chose comme ça:
SELECT * INTO #TempTable FROM SourceTable
Tant que cela fonctionne, cela crée des verrous contre la base de données tempdb pour le durée de l'instruction SELECT (pas mal de temps si vous parcourez dans beaucoup de données de la table source , et plus longtemps encore si SELECT ... INTO est au début d’un plus long transaction) Tant que le verrou est en place, aucun autre l'utilisateur peut créer des tables temporaires. Le l'emplacement réel du goulot d'étranglement est un verrouille les tables système tempdb. Au plus tard versions de SQL Server, le verrouillage le modèle a changé et le problème est évité.
Heureusement, ce n'était qu'un problème pour SQL 6.5. Il a été corrigé dans 7.0 et plus tard.
Cela va probablement flotter pendant un long moment, alimentant les poches de divers «consultants». Comme tous les mythes, il a un noyau de vérité et beaucoup de BS.
La vérité: SQL 2000 et les versions précédentes avaient connu des problèmes de conflit autour de l'allocation des étendues dans tempdb. La controverse était vraie dans toutes les bases de données, mais plus visible dans tempdb en raison d'une utilisation intensive de tempdb. Il est documenté dans KB328551 :
Lorsque la base de données tempdb est fortement chargée utilisé, SQL Server peut rencontrer conflit quand il essaie d'allouer pages.
Depuis la table système sysprocesses En sortie, la ressource peut apparaître comme "2: 1: 1" (page PFS) ou "2: 1: 3" (SGAM Page). En fonction du degré de conflit, cela peut également conduire à SQL Le serveur ne répond pas pour courtes périodes.
Ces opérations utilisent fortement tempdb:
Répétée créer et déposer de temporaire tables (locales ou globales).
Variables de table utilisant tempdb pour le stockage fins.
Tables de travail associées à CURSEURS.
Tables de travail associées à une clause ORDER BY.
Tables de travail associées à une clause GROUP BY.
Fichiers de travail associés aux plans de hachage.Utilisation lourde et significative de ceux-ci les activités peuvent mener à la contention problèmes.
Un indicateur de suivi -T1118
a été ajouté dans SQL Server 2000 SP3, ce qui forçait SQL à utiliser un algorithme alternatif pour les allocations de pages mixtes. Ce nouvel algorithme, une fois corrélé à la pratique consistant à déployer tempdb sur un ensemble de fichiers de taille égale, un pour chaque processeur, permettrait de réduire le conflit. L'indicateur de trace est toujours présent dans SQL 2005/2008, bien qu'il soit beaucoup moins nécessaire.
Tout le reste de ce mythe est à peu près BS.
Pour plus de détails, consultez cet article: Idées fausses autour de TF1118 .
Pourquoi ne pas faire ce qui suit?
SELECT X, Y, Z
INTO #MyTable
FROM YourTable
WHERE 1 = 2
L'instruction s'exécutera instantanément - créant votre table temporaire et évitant tout verrouillage possible. Ensuite, vous pouvez insérer comme d'habitude:
INSERT #MyTable
SELECT X, Y, Z
FROM YourTable
Vous pouvez obtenir un blocage si vous créez des tables #temp dans une transaction. Bien que cela ne soit généralement pas recommandé, j'ai souvent vu cela se faire.
Cependant, le blocage est dû à certaines tables système de tempdb qui n'affectent pas la création de tables temporaires par d'autres connexions (à l'exception peut-être des versions SQL antérieures à 2000?). Cela signifie que l'exécution de sp_spacesused sur tempdb bloquera sauf si vous définissez le niveau d'isolation de transaction sur lecture non validée. De plus, la visualisation des propriétés sur tempdb à partir de SSMS échouera et expirera sans aucun doute, car elle utilise le niveau d'isolation de transaction validée en lecture.
SELECT INTO #temp_table
conserve un verrou shema dans tempdb pour la durée de l'instruction, car une partie du travail qu'il accomplit consiste à créer la table. Ceci est fondamentalement différent de la création initiale de la table à l'aide de CREATE TABLE #....
, puis de l'exécution d'un INSERT basé sur un ensemble. SELECT INTO
présente des avantages par rapport à INSERT
, en particulier l'opération est journalisée de manière minimale si le modèle de récupération de la base de données est un journal simple ou en bloc.
Bien que SELECT INTO ait bloqué le blocage de la base de données tempdb, j’aimerais faire preuve de prudence lors de l’écriture du code, car certaines tables système sont bloquées lors des tests.
Référence: http://www.sqlservercentral.com/Forums/Topic1642797-2799-1.aspx
Je dirais que l'absence de preuve de verrouillage signifie pas de verrouillage, ce qui est votre preuve. Pourquoi la méthode dans laquelle la table temporaire est créée (CREATE ou SELECT ... INTO) aurait-elle une influence sur le verrouillage de TempDB?
Eh bien, si cela était vrai, alors mssql aurait des problèmes, car toute requête volumineuse peut utiliser tempdb pour conserver une copie des lignes. Cela se voit souvent dans les plans de requête sous forme de spool de table ou peut être utilisé par l'opérateur HASH JOIN s'il manque de mémoire pour ses compartiments.
Vous pouvez utiliser des variables de table que mssql essaiera de stocker en mémoire et de passer à tempdb si leur taille est trop grande.
DECLARE @foo TABLE (x int, y int, z int)
INSERT INTO @foo(x, y, z) SELECT x, y, z FROM YourTable
Bien sûr, vous devez évaluer si la table temporaire et la copie sont requises en premier. Bien que si la requête soit suffisamment complexe pour que l’utilisation d’une table temporaire soit beaucoup plus lisible, elle peut également être suffisamment complexe pour qu’une table temporaire en vaille la peine.