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

390

On m'a dit que si j'exportais la clé de deux tables, SQL Server créerait quelque chose de semblable à un index dans la table enfant. J'ai du mal à croire que cela soit vrai, mais je ne peux pas trouver grand-chose là-bas spécifiquement lié à cela.

Ma vraie raison de demander cela est parce que nous rencontrons un temps de réponse très lent dans une instruction de suppression par rapport à une table qui a probablement 15 tables liées. J'ai demandé à notre responsable de la base de données et il m'a dit que s'il y avait une clé étrangère dans les champs, cela agissait comme un index. Quelle est votre expérience avec cela? Dois-je ajouter des index sur tous les champs de clé étrangère ou s'agit-il simplement de frais généraux inutiles?

Nick DeVore
la source
J'ai la même compréhension que votre type DB - que les FK créent en fait un index.
Vinnie
9
Non - un FK ne crée PAS automatiquement un index. Il est logique d'en créer un - mais cela n'est PAS fait automatiquement par SQL Server.
marc_s
47
pas idiot de demander cela du tout!
marc_s
5
Si vous obtenez des suppressions lentes et la table que vous supprimez de référencé par d'autres tables, vous obtiendrez probablement une amélioration des performances en indexant les clés étrangères dans les autres tables. En effet, lorsque SQL supprime une ligne, il doit vérifier l'intégrité référentielle sur la ligne. Pour ce faire, il doit évidemment vérifier qu'aucune autre ligne n'existe référençant la ligne que vous supprimez.
Noel Kennedy,
3
Je dirais qu'un type de base de données qui ne le savait pas doit avoir sérieusement besoin de formation. Les gens de la base de données sont responsables de la performance, c'est leur travail de savoir ce genre de chose. Cela suggère une incompétence flagrante.
HLGEM

Réponses:

343

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

Mais c'est un fait connu qu'il est très logique d'indexer toutes les colonnes qui font partie d'une relation de clé étrangère, car grâce à une relation FK, vous devrez souvent rechercher une table associée et extraire certaines lignes en fonction de une seule valeur ou une plage de valeurs.

Il est donc judicieux 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é étrangère?" .

marc_s
la source
Oui. Je suis presque sûr que PostgreSQL crée un index. Je suis sûr que MySQL le fait. Faire l'index a beaucoup de sens, mais CE N'EST PAS REQUIS. Après tout, pourquoi référencer quelque chose si chaque fois que la base de données va la chercher, elle doit faire un scan de table?
MBCook
Cet article mentionné ci-dessus est un peu déroutant car SQL Server ou toute autre base de données ne met jamais d'index sur FK.
vsingh
7
@vsingh: c'est exactement ce que l'article essaie de transmettre - c'est une idée fausse courante qu'un FK crée automatiquement un index - il ne fait pas cela.
marc_s
5
@MBCook Non, PostgreSQL ne crée pas (au moins dans 9.2 ou toute version antérieure) automatiquement un index du côté de référence d'une relation de clé étrangère définie avec REFERENCES. Il crée automatiquement un UNIQUEindex pour une contrainte PRIMARY KEYor UNIQUEet requiert qu'un UNIQUEindex soit présent pour la fin référencée d'une relation de clé étrangère, mais ne fait rien automatiquement pour la fin de référencement , bien que ce soit souvent une bonne idée d'en créer un vous-même. Voir stackoverflow.com/questions/970562/…
Craig Ringer
16
La confusion peut exister car MySQL InnoDB requiert et crée automatiquement un index lorsque vous ajoutez une clé étrangère - dev.mysql.com/doc/refman/5.5/en/…
humbads
42

Wow, les réponses sont partout sur la carte. Donc, la documentation dit:

Une contrainte FOREIGN KEY est candidate à un index car:

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

  • Les colonnes de clé étrangère sont souvent utilisées dans les critères de jointure lorsque les données des tables associées sont combinées dans des requêtes en faisant correspondre les colonnes de la contrainte FOREIGN KEY d'une table avec les colonnes de clé principale ou unique de l'autre table. Un index permet à Microsoft® SQL Server ™ 2000 de trouver rapidement les données associées dans la table de clés étrangères. Cependant, la création de cet index n'est pas obligatoire. Les données de deux tables liées peuvent être combinées même si aucune contrainte PRIMARY KEY ou FOREIGN KEY 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 ses critères.

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

Yishai
la source
5
Exactement - c'est un CANDIDAT pour un index - mais il n'est pas automatiquement créé comme un seul! Très clair en fait, à
mon humble avis
4
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ère." Cela devrait se lire "... deux tableaux doivent être optimisés ..."
Yishai
18

Non, il n'y a pas d'index implicite sur les champs de clé étrangère, sinon pourquoi Microsoft dirait-il "La création d'un index sur une clé étrangère est souvent utile" . Votre collègue peut être source de confusion le champ de clé étrangère dans la table faisant référence à la clé primaire dans les visées à la table - clés primaires ne créer un index implicite.

Michael Borgwardt
la source
qu'est-ce qu'un "indice implicite"? cela signifie-t-il simplement qu'il y a un arbre ab * sans le créer?
Stephanie Page
1
@Stephanie Page: C'est une expression que je viens de compenser pour que cette réponse signifie un index qui est automatiquement créé. Si vous déclarez une clé primaire, SQL Server crée et indexe automatiquement celle-ci. Mais pas si vous déclarez une clé étrangère (certains autres systèmes DB le font).
Michael Borgwardt
7

SQL Server crée automatiquement des index pour les clés primaires, mais pas pour les clés étrangères. Créez l'index pour les clés étrangères. Cela vaut probablement les frais généraux.

Paul Sonier
la source
6

Supposons que vous ayez une grande table appelée commandes et une petite table appelée clients. Il existe une clé étrangère d'une commande à un client. Maintenant, si vous supprimez un client, Sql Server doit vérifier qu'il n'y a pas de commandes orphelines; s'il y en a, cela déclenche une erreur.

Pour vérifier s'il y a des commandes, Sql Server doit rechercher dans le tableau des grosses commandes. Maintenant, s'il y a un index, la recherche sera rapide; sinon, la recherche sera lente.

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

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

Andomar
la source
Exactement - c'est la raison pour laquelle un indice sur un FK a beaucoup de sens (la plupart du temps)
marc_s
1
La plupart du temps? Semble que c'est le cas pour une suppression d'un parent. Si la plupart du temps vous supprimez des parents, je suppose que c'est vrai.
Stephanie Page
6

Les clés étrangères ne créent pas d'index. Seules les contraintes de clé alternative (UNIQUE) et les contraintes de clé primaire créent des index. Cela est vrai dans Oracle et SQL Server.

Sandeep Kanuri
la source
3

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

Gandalf
la source
3

À proprement parler, les clés étrangères n'ont absolument rien à voir avec les index, oui. Mais, comme l'ont souligné les haut-parleurs au-dessus de moi, il est logique d'en créer un pour accélérer les recherches FK. En fait, dans MySQL, si vous ne spécifiez pas d'index dans votre déclaration FK, le moteur (InnoDB) le crée automatiquement pour vous.

shylent
la source
3

Dans PostgeSql, vous pouvez vérifier vous-même les index si vous appuyez sur \ d nom_table

Vous verrez que les index btree ont été créés automatiquement sur les colonnes avec clé primaire et contraintes uniques, mais pas sur les colonnes avec clé étrangère.

Je pense que cela répond à votre question au moins pour les postgres.

Gregor
la source
Désolé, je n'ai pas remarqué que la question concerne MS SQL Server mais après avoir posté la réponse. Cela pourrait probablement encore aider quelqu'un ...
Gregor
2

Je remarque que Entity Framework 6.1 pointé sur MSSQL ajoute automatiquement des index sur les clés étrangères.

Luke Puplett
la source
Je ne pense pas que ce soit le cas si vous marquez manuellement la colonne comme faisant partie d'un index (par exemple si vous créez un index composite sur plusieurs membres)
Rowland Shaw
0

InnoDB nécessite des index sur les clés étrangères et les clés référencées afin que les vérifications de clés étrangères puissent être rapides et ne nécessitent pas une analyse de table. Dans la table de référencement, il doit y avoir un index dans lequel les colonnes de clé étrangère sont répertoriées en tant que premières colonnes dans le même ordre.

Talha F.
la source