Dans EF Code First, la raison générale pour laquelle vous modélisez une relation de clé étrangère est la navigabilité entre les entités. Prenons un scénario simple de Country
et City
, avec un chargement hâtif défini pour l'instruction LINQ suivante :
var someQuery =
db.Countries
.Include(co => co.City)
.Where(co => co.Name == "Japan")
.Select(...);
Cela entraînerait une requête du type :
SELECT *
FROM Country co
INNER JOIN City ci
ON ci.CountryId = co.ID
WHERE co.Name = 'Japan';
Sans index sur la clé étrangère sur City.CountryId
, SQL devra analyser la table Cities afin de filtrer les villes pour le pays lors d'un JOIN.
L'index FK aura également des avantages en termes de performances si des lignes sont supprimées
à partir de la table Pays parent, car l'intégrité référentielle devra détecter la présence de toutes les lignes Ville liées (si le FK a ON CASCADE DELETE
défini ou non).
TL;DR
Index sur les clés étrangères sont recommandé , même si vous ne filtrez pas directement sur la clé étrangère, elle sera toujours nécessaire dans les jointures. Les exceptions à cela semblent assez artificielles :
-
Si la sélectivité de la clé étrangère est très faible, par ex. dans le scénario ci-dessus, si 50 % de TOUTES les villes du tableau des pays se trouvaient au Japon, l'indice ne serait pas utile.
-
Si vous ne parcourez jamais la relation.
-
Si vous ne supprimez jamais les lignes de la table parent (ou tentez de mettre à jour le PK) .
Une considération d'optimisation supplémentaire est de savoir s'il faut utiliser la clé étrangère dans l'Clustered Index
de la table enfant (c'est-à-dire le cluster Villes par pays). Ceci est souvent avantageux dans les relations parent :table enfant où il est courant de récupérer simultanément toutes les lignes enfant pour le parent.