web-dev-qa-db-fra.com

Dois-je créer des index sur des clés étrangères?

J'ai une table A et une table B. A a une clé étrangère pour B sur la clé primaire de B, B_ID.

Pour une raison quelconque (je sais qu'il existe des raisons légitimes), il ne s'agit pas d'un index lorsque je joins ces deux tables sur la clé.

Dois-je créer séparément un index sur A.B_ID ou l’existence d’une clé étrangère doit-elle le fournir?

109
aw crud

La contrainte de clé étrangère à elle seule ne fournit pas l'index - il faut (et devrait) être créé.

124
DCookie

La création d'une clé étrangère ne crée pas automatiquement un index sur A.B_ID. Il serait donc généralement logique, du point de vue des performances de la requête, de créer un index distinct sur A.B_ID.

Si vous supprimez des lignes dans B, vous voulez absolument que A.B_ID soit indexé. Sinon, Oracle devra effectuer une analyse complète du tableau sur A chaque fois que vous supprimez une ligne de B pour vous assurer qu'il n'y a pas d'enregistrements orphelins (en fonction de la version d'Oracle, d'autres implications en matière de verrouillage peuvent également exister, mais elles sont réduites. dans les versions Oracle les plus récentes).

42
Justin Cave

Juste pour plus d’informations: Oracle ne crée pas automatiquement d’index (comme pour les contraintes uniques) car (a) il n’est pas nécessaire d’appliquer la contrainte et (b) dans certains cas, vous n’en avez pas besoin.

La plupart du temps, cependant, vous voudrez créer un index (en fait, dans Oracle Apex, il existe un rapport sur les "clés étrangères non indexées").

Chaque fois que l'application doit pouvoir supprimer une ligne de la table parent ou mettre à jour la valeur PK (ce qui est plus rare), le DML pâtira de l'absence d'index car elle devra verrouiller l'intégralité de la table enfant.

Un cas où je choisis généralement pas d'ajouter un index est celui où le FK correspond à une table "données statiques" qui définit le domaine d'une colonne (par exemple une table de codes d'état), où les mises à jour et les suppressions sur la table parente ne sont jamais effectuées directement par l'application. Toutefois, si l'ajout d'un index sur la colonne présente des avantages pour les requêtes importantes de l'application, l'index sera tout de même une bonne idée.

23
Jeffrey Kemp

SQL Server n'a jamais mis automatiquement d'index sur les colonnes de clé étrangère - consultez le site de Kim Tripp excellent blog sur l'historique et l'histoire de ce mythe urbain.

C’est toutefois une bonne idée d’indexer vos colonnes de clé étrangère, c’est-à-dire qu’il est préférable de s’assurer que chaque colonne FK est sauvegardée par un index; pas nécessairement sur cette seule colonne - peut-être serait-il judicieux de créer un index sur deux ou trois colonnes avec la colonne FK comme première colonne. Cela dépend de votre scénario et de vos données.

12
marc_s

Pour des raisons de performances, un index doit être créé. Est utilisé dans les opérations de suppression sur la table primaire (pour vérifier que l'enregistrement que vous supprimez n'est pas utilisé) et dans les jointures impliquant généralement une clé étrangère. Seules quelques tables (je ne les crée pas dans les journaux) pourraient ne pas avoir besoin de l'index, mais probablement, dans ce cas, vous n'avez probablement pas besoin de la contrainte de clé étrangère.

MAIS

Certaines bases de données créent déjà automatiquement des index sur des clés étrangères. Jet Engine (fichiers Microsoft Access) MySQL Firebird

POUR SÛR

SQL Server Oracle

NE FAIT PAS

6
bubi

Comme pour tout ce qui a trait à la performance, cela dépend de nombreux facteurs et il n’existe pas de silve bullet p. Ex. dans un environnement très actif, le maintien d'un indice peut être inacceptable.

La sélectivité semble être la plus saillante: si les valeurs de l’index étaient fortement dupliquées, il pourrait être plus performant de supprimer l’index (si possible) et d’analyser les tables.

1
onedaywhen