clé primaire et index sql

106

Disons que j'ai une ligne ID (int) dans une base de données définie comme clé primaire. Si je demande souvent l'ID, dois-je également l'indexer? Ou est-ce que le fait d'être une clé primaire signifie qu'elle est déjà indexée?

La raison pour laquelle je demande est que dans MS SQL Server, je peux créer un index sur cet ID, qui, comme je l'ai dit, est ma clé primaire.

Edit: une question supplémentaire - cela fera-t-il du mal d'indexer en plus la clé primaire?

Danifo
la source

Réponses:

73

Vous avez raison, il est déroutant que SQL Server vous permette de créer des index en double sur le (s) même (s) champ (s). Mais le fait que vous puissiez en créer un autre n'indique pas que l'index PK n'existe pas déjà.

L'index supplémentaire ne sert à rien, mais le seul inconvénient (très faible) est la taille de fichier supplémentaire et la surcharge de création de lignes.

dkretz
la source
39
Les dommages causés par les index inutilisés sont en effet très nocifs. D'une part, les index consomment du stockage. D'autre part, cela ralentit les écritures et les mises à jour. Supprimez toujours les index qui ne seront pas utilisés.
Pacerier
50

Comme tout le monde l'a déjà dit, les clés primaires sont automatiquement indexées.

La création d'index supplémentaires sur la colonne de clé primaire n'a de sens que lorsque vous devez optimiser une requête qui utilise la clé primaire et certaines autres colonnes spécifiques. En créant un autre index sur la colonne de clé primaire et en incluant d'autres colonnes, vous pouvez atteindre l'optimisation souhaitée pour une requête.

Par exemple, vous avez une table avec de nombreuses colonnes, mais vous interrogez uniquement les colonnes ID, Nom et Adresse. En prenant l'ID comme clé primaire, nous pouvons créer l'index suivant qui est construit sur l'ID mais inclut les colonnes Nom et Adresse.

CREATE NONCLUSTERED INDEX MyIndex
ON MyTable(ID)
INCLUDE (Name, Address)

Ainsi, lorsque vous utilisez cette requête:

SELECT ID, Name, Address FROM MyTable WHERE ID > 1000

SQL Server vous donnera le résultat uniquement en utilisant l'index que vous avez créé et il ne lira rien de la table réelle.

trèfle rouge
la source
28

REMARQUE: cette réponse traite du développement de classe entreprise dans le grand .

Il s'agit d'un problème de SGBDR, pas seulement de SQL Server, et le comportement peut être très intéressant. D'une part, s'il est courant que les clés primaires soient automatiquement indexées (de manière unique), ce n'est PAS absolu. Il y a des moments où il est essentiel qu'une clé primaire ne soit PAS indexée de manière unique.

Dans la plupart des SGBDR, un index unique sera automatiquement créé sur une clé primaire s'il n'en existe pas déjà une . Par conséquent, vous pouvez créer votre propre index sur la colonne de clé primaire avant de le déclarer comme clé primaire, puis cet index sera utilisé (s'il est acceptable) par le moteur de base de données lorsque vous appliquez la déclaration de clé primaire. Souvent, vous pouvez créer la clé primaire et autoriser la création de son index unique par défaut, puis créer votre propre index alternatif sur cette colonne, puis supprimer l'index par défaut.

Maintenant, pour la partie amusante - quand ne voulez-vous PAS un index de clé primaire unique? Vous n'en voulez pas et ne pouvez pas en tolérer un, lorsque votre table acquiert suffisamment de données (lignes) pour rendre la maintenance de l'index trop coûteuse. Cela varie en fonction du matériel, du moteur SGBDR, des caractéristiques de la table et de la base de données et de la charge du système. Cependant, il commence généralement à se manifester une fois qu'une table atteint quelques millions de lignes.

Le problème essentiel est que chaque insertion d'une ligne ou mise à jour de la colonne de clé primaire entraîne une analyse d'index pour garantir l'unicité. Cette analyse d'index unique (ou son équivalent dans n'importe quel SGBDR) devient beaucoup plus coûteuse à mesure que la table grandit, jusqu'à ce qu'elle domine les performances de la table.

J'ai traité ce problème à plusieurs reprises avec des tables de deux milliards de lignes, 8 To de stockage et quarante millions d'insertions de lignes par jour. J'ai été chargé de repenser le système impliqué, ce qui comprenait la suppression de l'index de clé primaire unique pratiquement comme première étape. En effet, l'abandon de cet indice était nécessaire en production simplement pour se remettre d'une panne, avant même de se rapprocher d'une refonte. Cette refonte comprenait la recherche d'autres moyens d'assurer l'unicité de la clé primaire et de fournir un accès rapide aux données.

Rob Williams
la source
Que faire si la clé est une clé d'auto-incrémentation int ou bigint? SQL Server est-il suffisamment intelligent pour ne pas effectuer une analyse d'index unique dans ce cas?
quillbreaker
1
@quillbreaker: il IDENTITYn'est pas garanti qu'un champ soit unique. Après tout, les utilisateurs peuvent insérer des valeurs en double s'ils utilisent IDENTITY_INSERT.
Je sais que c'est un sujet ancien, mais je ne comprends pas comment une analyse d'unicité d'un index serait une telle charge sur le système. Une analyse d'arbre B + doit être O (log n) * v où v est une surcharge contrainte pour la fragmentation d'index, l'équilibre imparfait de l'arbre, etc. 2 ou 3 ou même 10. 40M inserts par jour, c'est environ 462 / sec, ~ 100 IO par insert ... Ahh ... Oh. Je vois. Et c'était avant les SSD répandus.
Charles Burns
À moins que vous n'ayez supprimé la contrainte d'unicité, la surcharge de vérification de chacune des lignes pour l'unicité ne serait-elle pas beaucoup plus grande?
Max Candocia
21

Les clés primaires sont toujours indexées par défaut.

Vous pouvez définir une clé primaire dans SQL Server 2012 à l'aide de SQL Server Management Studio ou Transact-SQL. La création d'une clé primaire crée automatiquement un index correspondant unique, clusterisé ou non clusterisé.

http://technet.microsoft.com/en-us/library/ms189039.aspx

jcollum
la source
9

Voici le passage du MSDN :

Lorsque vous spécifiez une contrainte PRIMARY KEY pour une table, le moteur de base de données applique l'unicité des données en créant un index unique pour les colonnes de clé primaire. Cet index permet également un accès rapide aux données lorsque la clé primaire est utilisée dans les requêtes. Par conséquent, les clés primaires choisies doivent suivre les règles de création d'index uniques.

MicSim
la source
8

un PK deviendra un index clusterisé sauf si vous spécifiez non clusterisé

SQLMenace
la source
3

La déclaration d'une contrainte PRIMARY KEYou UNIQUEoblige SQL Server à créer automatiquement un index.

Un index unique peut être créé sans correspondre à une contrainte, mais une contrainte (clé primaire ou unique) ne peut pas exister sans un index unique.

A partir de là, la création d'une contrainte va:

  • provoquer la création d'un index avec le même nom
  • refuser de supprimer l'index créé car la contrainte n'est pas autorisée à exister sans elle

et en même temps la suppression de la contrainte supprimera l'index associé.

Alors, y a-t-il une différence réelle entre un PRIMARY KEYou UNIQUE INDEX:

  • NULLles valeurs ne sont pas autorisées dans PRIMARY KEY, mais autorisées dans l' UNIQUEindex; et comme dans les opérateurs d'ensemble (UNION, SAUF, INTERSECT), ici NULL = NULLce qui signifie que vous ne pouvez avoir qu'une seule valeur car deux NULLs sont trouvés comme des doublons l'un de l'autre;
  • un seul PRIMARY KEYpeut exister par table alors que 999 index uniques peuvent être créés
  • lorsque la PRIMARY KEYcontrainte est créée, elle est créée en cluster sauf s'il existe déjà un index clusterisé sur la table ou NONCLUSTEREDest utilisée dans sa définition; lorsque l' UNIQUEindex est créé, il est créé comme à NONCLUSTEREDmoins qu'il ne soit pas spécifique d'être CLUSTEREDet que tel n'existe pas déjà;
gotqn
la source
2

En faire une clé primaire devrait également créer automatiquement un index pour elle.

EJ Brennan
la source
1

Eh bien dans SQL Server, généralement, la clé primaire est automatiquement indexée. C'est vrai, mais cela ne garantit pas une requête plus rapide. La clé primaire vous donnera d'excellentes performances lorsqu'il n'y a qu'un seul champ comme clé primaire. Mais, lorsqu'il existe plusieurs champs comme clé primaire, l'index est basé sur ces champs.

Par exemple: les champs A, B, C sont la clé primaire, donc lorsque vous effectuez une requête basée sur ces 3 champs dans votre CLAUSE WHERE, les performances sont bonnes, MAIS lorsque vous souhaitez interroger avec le champ Only C dans la CLAUSE WHERE, vous n'obtiendra pas de bonnes performances. Ainsi, pour que vos performances soient opérationnelles, vous devrez indexer le champ C manuellement.

La plupart du temps, vous ne verrez pas le problème jusqu'à ce que vous atteigniez plus d'un million d'enregistrements.

Susanto Siman
la source
0

J'ai une énorme base de données sans index (séparé).

Chaque fois que j'interroge par la clé primaire, les résultats sont, à toutes fins intensives, instantanés.

Subvention
la source
En effet, le PK est un index clusterisé, regardez votre plan de requête
SQLMenace
0

les clés primaires sont automatiquement indexées

vous pouvez créer des indices supplémentaires en utilisant le pk en fonction de votre utilisation

  • index zip_code, id peut être utile si vous sélectionnez souvent par zip_code et id
mson
la source