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

120

J'ai une table Aet une table B. Aa une clé étrangère Bsur la Bclé primaire », B_ID.

Pour une raison quelconque (je sais qu'il y a des raisons légitimes), il n'utilise pas d'index lorsque je joins ces deux tables sur la clé.

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

aw crud
la source

Réponses:

137

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

DCookie
la source
11
Sur certaines bases de données, la création d'une contrainte de clé étrangère crée également un index ... ie Jet Engine (fichiers MSAccess, Firebird et MySQL)
bubi
17
Cette réponse n'a pas de sens sans se référer explicitement à une implémentation de base de données particulière. Bien sûr, la question est balisée, oraclemais ce n'est pas immédiatement évident lorsque vous arrivez ici à partir d'une recherche Google.
developerbmw
5
Je peux confirmer que PostgreSQL - du moins au moment de cet article - ne le fait pas automatiquement.
The Dembinski
Même réponse pour SQL Server (2016, Azure ...), pour autant que je sache.
Pac0
Pourquoi faut-il créer un index sur une clé étrangère avec Oracle? Quelles sont les conséquences de ne pas le faire, s'il vous plaît?
Đỗ Công Bằng
46

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 des requêtes de créer un index distinct sur A.B_ID.

Si jamais vous supprimez des lignes dans B, vous voulez certainement que A.B_ID soit indexé. Sinon, Oracle devra effectuer une analyse complète de la table sur A chaque fois que vous supprimez une ligne de B pour vous assurer qu'il n'y a pas d'enregistrements orphelins (selon la version d'Oracle, il peut y avoir des implications de verrouillage supplémentaires, mais celles-ci sont diminuées dans les versions Oracle plus récentes).

Justin Cave
la source
1
Qu'en est-il des colonnes PFK? par exemple si j'ai une table intermédiaire pour une relation plusieurs-à-plusieurs, sholud je crée un index pour les deux colonnes PFK de cette table?
Clamari
3
@Clamari - Si C a une clé primaire de (A_ID, B_ID), la clé primaire se chargerait de pouvoir supprimer de A. Si vous voulez également pouvoir supprimer de B efficacement, vous voudriez un index sur B_ID.
Justin Cave le
25

Juste pour plus d'informations: Oracle ne crée pas d'index automatiquement (comme il le fait 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 y a un rapport de "clés étrangères non indexées").

Chaque fois que l'application doit pouvoir supprimer une ligne dans la table parent, ou mettre à jour la valeur PK (qui est plus rare), le DML souffrira si aucun index n'existe, car il devra verrouiller la table enfant entière.

Un cas où je choisis généralement de ne pas ajouter d'index est celui où le FK se trouve dans une table de "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 de la table parent ne sont jamais effectuées directement par l'application. Cependant, si l'ajout d'un index sur la colonne présente des avantages pour des requêtes importantes dans l'application, l'index sera toujours une bonne idée.

Jeffrey Kemp
la source
14

SQL Server n'a jamais mis automatiquement d'index sur des colonnes de clés étrangères - consultez l' excellent article de blog de Kim Tripp sur le contexte et l'histoire de ce mythe urbain.

Cependant, c'est généralement une bonne idée d'indexer vos colonnes de clé étrangère - donc oui, je recommanderais de vous assurer que chaque colonne FK est sauvegardée par un index; pas nécessairement sur cette seule colonne - peut-être qu'il peut être judicieux de créer un index sur deux ou trois colonnes avec la colonne FK comme première. Dépend de votre scénario et de vos données.

marc_s
la source
8

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 qui impliquent 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) Firebird MySQL

POUR SÛR

Oracle SQL Server

NE FAIT PAS

bubi
la source
3
Merci d'avoir mentionné que FIrebird SQL le fait automatiquement. C'est exactement le point que je recherchais.
user424855
1

Comme pour tout ce qui concerne les performances, cela dépend de nombreux facteurs et il n'y a pas de balle silencieuse, par exemple dans un environnement très actif, le maintien d'un index peut être inacceptable.

Le plus important ici semble être la sélectivité: si les valeurs de l'index sont fortement dupliquées, cela peut donner de meilleures performances pour supprimer l'index (si possible) et permettre un balayage de table.

un jour quand
la source
1

Les contraintes UNIQUE, PRIMARY KEY et FOREIGN KEY génèrent des index qui appliquent ou «rétrogradent» la contrainte (et sont parfois appelés index de sauvegarde). Les contraintes PRIMARY KEY génèrent des index uniques. Les contraintes FOREIGN KEY génèrent des index non uniques. Les contraintes UNIQUE génèrent des index uniques si toutes les colonnes ne sont pas Nullables et génèrent des index non uniques si une ou plusieurs colonnes sont Nullables. Par conséquent, si une colonne ou un ensemble de colonnes a une contrainte UNIQUE, PRIMARY KEY ou FOREIGN KEY, vous n'avez pas besoin de créer un index sur ces colonnes pour les performances.

Chinmai
la source
Les documents auxquels vous avez lié sont destinés à Derby, la base de données Java intégrée, et non à Oracle.
Davos