468 votes

Une clé étrangère crée-t-elle automatiquement un index ?

On m'a dit que si j'utilise une clé étrangère pour deux tables, le serveur SQL créera quelque chose de semblable à un index dans la table enfant. J'ai du mal à croire que cela soit vrai, mais je ne trouve pas grand-chose de spécifique à ce sujet.

Si je vous pose cette question, c'est parce que le temps de réponse d'une instruction de suppression d'une table qui comporte probablement 15 tables connexes est très lent. J'ai demandé à notre responsable de la base de données et il m'a répondu que s'il existe une clé étrangère sur les champs, elle agit comme un index. Quelle est votre expérience à ce sujet ? Devrais-je ajouter des index sur tous les champs de clé étrangère ou bien s'agit-il simplement d'une surcharge inutile ?

0 votes

J'ai la même compréhension que votre responsable de la base de données - que les FKs créent en fait un index.

13 votes

Non - un FK le fait PAS créer automatiquement un index. Il est logique d'en créer un - mais c'est PAS fait automatiquement par le serveur SQL.

55 votes

Ce n'est pas du tout idiot de demander cela !

420voto

marc_s Points 321990

Une clé étrangère est une contrainte, une relation entre deux tables, qui n'a rien à voir avec un index en soi.

Mais il est bien connu qu'il est très utile d'indexer toutes les colonnes qui font partie d'une relation de clé étrangère, car par le biais d'une relation de clé étrangère, vous aurez souvent besoin de consulter une table de référence et d'extraire certaines lignes sur la base d'une seule valeur ou d'une plage de valeurs.

Il est donc logique d'indexer toutes les colonnes impliquées dans un FK, mais un FK en soi n'est pas un index.

Consultez l'excellent article de Kimberly Tripp. "Quand SQL Server a-t-il cessé de mettre des index sur les colonnes de clés étrangères ?" .

0 votes

Ouaip. Je suis presque sûr que PostgreSQL crée un index. Je suis presque sûr que MySQL le fait. Créer l'index a beaucoup de sens, mais CE N'EST PAS OBLIGATOIRE. Après tout, pourquoi référencer quelque chose si à chaque fois que la BD va le chercher, elle doit faire un tablescan ?

0 votes

L'article mentionné ci-dessus est un peu confus parce que le serveur SQL ou toute autre base de données ne met jamais un index sur FK.

7 votes

@vsingh : c'est exactement ce que l'article essaie de faire comprendre - c'est une pratique courante. idée fausse qu'un FK crée automatiquement un index - il le fait. pas faire ça.

55voto

Yishai Points 42417

Wow, les réponses sont toutes sur la carte. Donc le Documentation dit :

Une contrainte FOREIGN KEY est un candidat pour un index car :

  • Les modifications apportées aux contraintes PRIMARY KEY sont vérifiées avec les contraintes FOREIGN KEY dans les tables liées.

  • Les colonnes de clé étrangère sont souvent utilisées dans les critères de jointure lorsque les données de tables liées sont combinées dans des requêtes en faisant correspondre la ou les colonnes de la contrainte FOREIGN KEY d'une table avec la ou les colonnes de clé primaire ou unique de l'autre table. Un index permet à Microsoft® SQL Server™ 2000 de trouver rapidement les données connexes dans la table à clé étrangère. Cependant, la création de cet index n'est pas une obligation. Les données de deux tables liées peuvent être combinées même si aucune contrainte de clé primaire ou de clé étrangère n'est définie entre les tables, mais une relation de clé étrangère entre deux tables indique que les deux tables ont été optimisées pour être combinées dans une requête qui utilise les clés comme critères.

Il semble donc assez clair (bien que la documentation soit un peu confuse) qu'elle ne crée pas d'index en fait.

6 votes

Exactement - c'est un CANDIDAT pour un index - mais il n'est pas automatiquement créé comme tel ! C'est assez clair en fait, IMHO :-)

7 votes

J'ai trouvé cette partie confuse : "une relation de clé étrangère entre deux tables indique que les deux tables ont été optimisées pour être combinées dans une requête qui utilise les clés comme critères." Il faut lire "... deux tables doivent être optimisées...".

26voto

Michael Borgwardt Points 181658

Non, il n'y a pas d'index implicite sur les champs de clé étrangère, sinon pourquoi Microsoft dirait-il "Créer un index sur une clé étrangère est souvent utile" . Votre collègue confond peut-être le champ de la clé étrangère dans la table de référence avec la clé primaire dans la table de référence - clés primaires faire créer un index implicite.

1 votes

Qu'est-ce qu'un "index implicite" ? cela implique-t-il simplement qu'il existe un b*tree sans le créer ?

1 votes

@Stephanie Page : C'est une expression que je viens d'inventer pour cette réponse pour désigner un index qui est créé automatiquement. Si vous déclarez une clé primaire, le serveur SQL crée automatiquement un index pour celle-ci. Mais pas si vous déclarez une clé étrangère (certains autres systèmes de BD le font).

8voto

Andomar Points 115404

Disons que vous avez une grande table appelée commandes, et une petite table appelée clients. Il existe une clé étrangère entre une commande et un client. Maintenant, si vous supprimez un client, Sql Server doit vérifier qu'il n'y a pas de commandes orphelines ; si c'est le cas, il émet une erreur.

Pour vérifier s'il y a des commandes, Sql Server doit chercher dans la grande table des commandes. Maintenant, s'il y a un index, la recherche sera rapide ; s'il n'y en a pas, la recherche sera lente.

Ainsi, dans ce cas, la lenteur de la suppression pourrait s'expliquer par l'absence d'un index. Surtout si Sql Server devait rechercher 15 grandes tables sans index.

P.S. Si la clé étrangère a ON DELETE CASCADE, Sql Server doit toujours chercher dans la table des commandes, mais ensuite supprimer toutes les commandes qui font référence au client supprimé.

0 votes

Exactement - c'est la raison pour laquelle un index sur un FK a beaucoup de sens (la plupart du temps).

1 votes

La plupart du temps ? Il semble que ce soit le cas pour une suppression d'un parent. Si la plupart du temps vous supprimez des parents, je suppose que c'est vrai.

3voto

Gandalf Points 4909

Pas à ma connaissance. Une clé étrangère ajoute seulement une contrainte selon laquelle la valeur de la clé enfant doit également être représentée quelque part dans la colonne parent. Elle ne dit pas à la base de données que la clé enfant doit aussi être indexée, mais seulement contrainte.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X