Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Créer un index sur une variable de table

La question est étiquetée SQL Server 2000 mais pour le bénéfice des personnes développant 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 directement des index non uniques avec une syntaxe en ligne sur les déclarations de variables de table.

Un 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*/
);

Les index filtrés et les index avec des colonnes incluses ne peuvent actuellement pas être déclarés avec cette syntaxe cependant SQL Server 2016 assouplit cela un peu plus. A partir de CTP 3.1, il est désormais possible de déclarer des index filtrés pour les variables de table. Par RTM, il peut être le cas où les colonnes incluses sont également autorisées, mais la position actuelle est qu'elles "n'entreront probablement pas dans SQL16 en raison de 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 Name ?

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.

Les tables traditionnelles dans SQL Server peuvent avoir un index clusterisé ou être structurées sous forme de tas.

Les index clusterisés peuvent soit être déclarés comme uniques pour interdire les valeurs de clé en double, soit être par défaut non uniques. S'il n'est pas unique, SQL Server ajoute silencieusement un uniqueificateur à 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 ligne (clé d'index cluster ou RID pour un tas) à toutes les clés d'index (pas seulement les doublons), ce qui 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 un UNIQUE ou PRIMARY KEY contrainte. La différence entre ces types de contraintes est que la clé primaire doit être sur une ou plusieurs colonnes non nullables. Les colonnes participant à une contrainte unique peuvent être nullables. (bien que l'implémentation par SQL Server de contraintes uniques en présence de NULL s n'est pas conforme à ce qui est spécifié 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 non spécifié explicitement, la PRIMARY KEY deviendra l'index clusterisé et les contraintes uniques non clusterisées mais ce comportement peut être remplacé 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
)

À la suite de ce qui précède, les index suivants peuvent être implicitement créés sur des 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 demande un peu d'explication. Dans la définition de la variable de tableau au début de cette réponse, le non unique index non clusterisé sur Name est simulé par un unique index sur Name,Id (rappelez-vous que SQL Server ajouterait de toute façon silencieusement la clé d'index clusterisée à la clé NCI non unique).

Un index clusterisé non unique peut également être obtenu en ajoutant manuellement un IDENTITY colonne pour agir en tant qu'unificateur.

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 clusterisé non unique serait normalement implémenté dans SQL Server car cela ajoute le "Uniqueifier" à toutes les lignes. Pas seulement ceux qui en ont besoin.