Question

Pouvez-vous créer un index sur une variable de table SQL Server 2000?

i.e..

DECLARE @TEMPTABLE TABLE (
        [ID] [int] NOT NULL PRIMARY KEY
        ,[Name] [nvarchar] (255) COLLATE DATABASE_DEFAULT NULL 
)

Puis-je créer un index sur nom?

Était-ce utile?

La solution

La question est étiquetée SQL Server 2000, mais au profit des personnes en développement sur la dernière version, je vais répondre à cette première.

SQL Server 2014

En plus des méthodes d'ajout d'index à base de contraintes décrites ci-dessous SQL Server 2014 permet également des index non uniques à spécifier directement avec la syntaxe en ligne sur les déclarations de variables de table.

exemple de syntaxe pour cela est ci-dessous.

/*SQL Server 2014+ compatible inline index syntax*/
DECLARE @T TABLE (
C1 INT INDEX IX1 CLUSTERED, /*Single column indexes can be declared next to the column*/
C2 INT INDEX IX2 NONCLUSTERED,
       INDEX IX3 NONCLUSTERED(C1,C2) /*Example composite index*/
);

index et index avec Filtré colonnes incluses peuvent pas être déclarés avec cette syntaxe mais SQL Server 2016 se détend un peu plus loin. De CTP 3.1, il est maintenant possible de déclarer des index filtrés pour les variables de table. Par RTM il peut être le cas incluant des colonnes sont également autorisés, mais la position actuelle est qu'ils « sera probablement pas faire dans SQL16 en raison des contraintes de ressources »

/*SQL Server 2016 allows filtered indexes*/
DECLARE @T TABLE
(
c1 INT NULL INDEX ix UNIQUE WHERE c1 IS NOT NULL /*Unique ignoring nulls*/
)

SQL Server 2000 - 2012

  

Puis-je créer un index sur nom?

Réponse courte: Oui.

DECLARE @TEMPTABLE TABLE (
  [ID]   [INT] NOT NULL PRIMARY KEY,
  [Name] [NVARCHAR] (255) COLLATE DATABASE_DEFAULT NULL,
  UNIQUE NONCLUSTERED ([Name], [ID]) 
  ) 

Une réponse plus détaillée est ci-dessous.

Tables classiques dans SQL Server peuvent soit avoir un index ordonné en clusters ou sont structurés comme tas .

Les index clusterisés peuvent soit être déclarés comme unique de désavouer en double des valeurs clés ou défaut non unique. Si donc pas unique SQL Server ajoute silencieusement un uniqueifier pour toutes les clés en double pour les rendre uniques.

index non cluster peuvent également être explicitement déclarés comme unique. Dans le cas contraire pour le cas non unique de SQL Server ajoute le localisateur de ligne (clé d'index cluster ou RID pour un tas) à toutes les clés d'index (pas seulement doublons) ce nouveau assure qu'ils sont uniques.

Dans SQL Server 2000 - 2012 index sur les variables de table ne peuvent être créés implicitement en créant une contrainte de UNIQUE ou PRIMARY KEY. La différence entre ces types de contraintes sont que la clé primaire doit être sur la colonne non annulable (s). Les colonnes qui participent à une contrainte unique peut être annulable. (Bien que la mise en œuvre de SQL Server de contraintes uniques en présence de NULLs n'est pas par celui spécifié dans la norme SQL). Aussi une table ne peut avoir une clé primaire, mais de multiples contraintes uniques.

Ces deux contraintes logiques sont mises en œuvre physiquement avec un index unique. Dans le cas contraire explicitement spécifiée, sinon le PRIMARY KEY deviendra l'index cluster et les contraintes uniques non cluster mais ce comportement peut être annulé en spécifiant CLUSTERED ou NONCLUSTERED explicitement avec la déclaration de contrainte (Exemple de syntaxe)

DECLARE @T TABLE
(
A INT NULL UNIQUE CLUSTERED,
B INT NOT NULL PRIMARY KEY NONCLUSTERED
)

En conséquence de ce qui précède les indices suivants peuvent être créés implicitement sur les variables de table dans SQL Server 2000 -. 2012

+-------------------------------------+-------------------------------------+
|             Index Type              | Can be created on a table variable? |
+-------------------------------------+-------------------------------------+
| Unique Clustered Index              | Yes                                 |
| Nonunique Clustered Index           |                                     |
| Unique NCI on a heap                | Yes                                 |
| Non Unique NCI on a heap            |                                     |
| Unique NCI on a clustered index     | Yes                                 |
| Non Unique NCI on a clustered index | Yes                                 |
+-------------------------------------+-------------------------------------+

Le dernier exige un peu d'explication. Dans la définition de table variable au début de cette réponse l'indice non uniques non cluster sur Name est simulé par un uniques index sur Name,Id (rappelons que SQL Server ajouterait silencieusement clé d'index cluster à la clé NCI non unique, de toute façon).

Un index cluster non unique peut également être obtenue en ajoutant manuellement une colonne IDENTITY pour agir comme un uniqueifier.

DECLARE @T TABLE
(
A INT NULL,
B INT NULL,
C INT NULL,
Uniqueifier INT NOT NULL IDENTITY(1,1),
UNIQUE CLUSTERED (A,Uniqueifier)
)

Mais ce n'est pas une simulation précise de la façon dont un index ordonné en clusters non unique, seraitnormalement être mis en œuvre effectivement dans SQL Server, car cela ajoute le « Uniqueifier » à toutes les lignes. Non seulement ceux qui en ont besoin.

Autres conseils

Il faut comprendre que du point de vue de la performance, il n'y a pas de différences entre les tables de @temp et les tables de #temp qui favorisent les variables. Ils résident au même endroit (tempdb) et sont mises en œuvre de la même manière. Toutes les différences apparaissent dans des fonctions supplémentaires. Voir cet article intitulée étonnamment complet: https://dba.stackexchange.com/questions/16385/whats-the-difference-between-a-temp-table-and-table-variable-in-sql-server/16386#16386

Bien qu'il y ait des cas où une table temporaire ne peut pas être utilisé comme dans la table ou fonctions scalaires, pour la plupart des autres cas avant v2016 (où peuvent être ajoutés à une variable de table index même filtrés), vous pouvez simplement utiliser un # table temporaire.

L'inconvénient de l'utilisation des index nommés (ou contraintes) dans tempdb est que les noms peuvent alors entrer en conflit. Non seulement en théorie, avec d'autres procédures, mais souvent assez facilement avec d'autres instances de la procédure elle-même qui essaierait de mettre le même index sur sa copie de la table #temp.

Pour éviter les conflits de noms, quelque chose comme cela fonctionne habituellement:

declare @cmd varchar(500)='CREATE NONCLUSTERED INDEX [ix_temp'+cast(newid() as varchar(40))+'] ON #temp (NonUniqueIndexNeeded);';
exec (@cmd);

Ceci assure le nom est toujours unique, même entre les exécutions simultanées de la même procédure.

Si la variable tableau a de grandes données, puis au lieu de la variable de table (@Table) créer de table temporaire (#table) Variable .table ne permet pas de créer un index après insertion.

 CREATE TABLE #Table(C1 int,       
  C2 NVarchar(100) , C3 varchar(100)
  UNIQUE CLUSTERED (c1) 
 ); 
  1. Créer table avec index cluster unique

  2. Insérer des données dans le tableau Temp "#table"

  3. Créer des index non cluster.

     CREATE NONCLUSTERED INDEX IX1  ON #Table (C2,C3);
    
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top