Pouvez-vous créer un index sur une variable de table dans SQL Server 2000?
c'est à dire
DECLARE @TEMPTABLE TABLE (
[ID] [int] NOT NULL PRIMARY KEY
,[Name] [nvarchar] (255) COLLATE DATABASE_DEFAULT NULL
)
Puis-je créer un index sur Name
?
sql
sql-server
tsql
indexing
table-variable
GordyII
la source
la source
CREATE TABLE #T1(X INT); CREATE TABLE #T2(X INT); CREATE INDEX IX ON #T1(X); CREATE INDEX IX ON #T2(X);
Réponses:
La question est étiquetée SQL Server 2000, mais pour le bénéfice des personnes qui développent sur la dernière version, je vais d'abord y répondre.
SQL Server 2014
En plus des méthodes d'ajout d'index basés sur des contraintes décrites ci-dessous, SQL Server 2014 permet également de spécifier des index non uniques directement avec la syntaxe en ligne sur les déclarations de variables de table.
Un exemple de syntaxe pour cela est ci-dessous.
Les index filtrés et les index avec des colonnes incluses ne peuvent actuellement pas être déclarés avec cette syntaxe, mais SQL Server 2016 assouplit cela un peu plus. Depuis CTP 3.1, il est désormais possible de déclarer des index filtrés pour les variables de table. Par RTM, il se peut que les colonnes incluses soient également autorisées, mais la position actuelle est qu'elles "ne parviendront probablement pas à entrer dans SQL16 en raison de contraintes de ressources"
SQL Server 2000 - 2012
Réponse courte: Oui.
Une réponse plus détaillée est ci-dessous.
Les tables traditionnelles dans SQL Server peuvent avoir un index clusterisé ou être structurées sous forme de tas .
Les index en cluster peuvent être déclarés comme uniques pour interdire les valeurs de clé en double ou être par défaut non uniques. S'il n'est pas unique, SQL Server ajoute silencieusement un identificateur à toutes les clés en double pour les rendre uniques.
Les index non clusterisés peuvent également être explicitement déclarés comme uniques. Sinon, pour le cas non unique, SQL Server ajoute le localisateur de lignes (clé d'index cluster ou RID pour un tas) à toutes les clés d'index (pas seulement les doublons), cela garantit à nouveau qu'elles sont uniques.
Dans SQL Server 2000-2012, les index sur les variables de table ne peuvent être créés implicitement qu'en créant une contrainte
UNIQUE
ouPRIMARY KEY
. La différence entre ces types de contraintes réside dans le fait que la clé primaire doit se trouver sur des colonnes non nullables. Les colonnes participant à une contrainte unique peuvent être nulles. (bien que l'implémentation par SQL Server de contraintes uniques en présence deNULL
s ne soit pas conforme à celle spécifiée dans la norme SQL). De plus, une table ne peut avoir qu'une seule clé primaire mais plusieurs contraintes uniques.Ces deux contraintes logiques sont physiquement implémentées avec un index unique. Si ce n'est pas spécifié explicitement, le
PRIMARY KEY
deviendra l'index clusterisé et les contraintes uniques non groupées mais ce comportement peut être remplacé en spécifiantCLUSTERED
ouNONCLUSTERED
explicitement avec la déclaration de contrainte (Exemple de syntaxe)En raison de ce qui précède, les index suivants peuvent être créés implicitement sur des variables de table dans SQL Server 2000-2012.
Le dernier demande un peu d'explication. Dans la définition de variable de table au début de cette réponse, l' index non unique non clusterisé
Name
est simulé par un index unique activéName,Id
(rappelez-vous que SQL Server ajouterait de toute façon la clé d'index clusterisé à la clé NCI non unique).Un index cluster non unique peut également être obtenu en ajoutant manuellement une
IDENTITY
colonne pour agir comme un unique.Mais ce n'est pas une simulation précise de la façon dont un index cluster non unique serait normalement implémenté dans SQL Server car cela ajoute le "Uniqueifier" à toutes les lignes. Pas seulement ceux qui en ont besoin.
la source
Il faut comprendre que du point de vue des performances, il n'y a aucune différence entre les tables @temp et les tables #temp qui favorisent les variables. Ils résident au même endroit (tempdb) et sont implémentés de la même manière. Toutes les différences apparaissent dans des fonctionnalités supplémentaires. Voir cet article incroyablement complet: /dba/16385/whats-the-difference-between-a-temp-table-and-table-variable-in-sql-server/16386#16386
Bien qu'il existe des cas où une table temporaire ne peut pas être utilisée, comme dans des fonctions de table ou scalaires, dans la plupart des autres cas antérieurs à la v2016 (où même des index filtrés peuvent être ajoutés à une variable de table), vous pouvez simplement utiliser une table #temp.
L'inconvénient d'utiliser des index nommés (ou des contraintes) dans tempdb est que les noms peuvent alors entrer en conflit. Pas seulement théoriquement avec d'autres procédures, mais souvent assez facilement avec d'autres instances de la procédure elle-même qui essaieraient de mettre le même index sur sa copie de la table #temp.
Pour éviter les conflits de noms, quelque chose comme ça fonctionne généralement:
Cela garantit que le nom est toujours unique, même entre les exécutions simultanées de la même procédure.
la source
Si la variable de table a des données volumineuses, alors au lieu de la variable de table (@table), créez une table temporaire (#table) .table variable ne permet pas de créer un index après l'insertion.
Créer une table avec un index clusterisé unique
Insérer des données dans la table Temp "#Table"
Créez des index non clusterisés.
la source