In EF Code First is de algemene reden waarom u een externe-sleutelrelatie zou modelleren de bevaarbaarheid tussen entiteiten. Overweeg een eenvoudig scenario van Country
en City
, met gretig laden gedefinieerd voor het volgende LINQ-statement:
var someQuery =
db.Countries
.Include(co => co.City)
.Where(co => co.Name == "Japan")
.Select(...);
Dit zou resulteren in een zoekopdracht in de trant van:
SELECT *
FROM Country co
INNER JOIN City ci
ON ci.CountryId = co.ID
WHERE co.Name = 'Japan';
Zonder een Index op de refererende sleutel op City.CountryId
, moet SQL de tabel Steden scannen om de steden voor het land te filteren tijdens een JOIN.
De FK-index heeft ook prestatievoordelen als rijen worden verwijderd
uit de bovenliggende landentabel, aangezien referentiële integriteit de aanwezigheid van gekoppelde stadsrijen moet detecteren (of de FK ON CASCADE DELETE
heeft gedefinieerd of niet).
TL;DR
Indexen op buitenlandse sleutels zijn aanbevolen , zelfs als u niet rechtstreeks op de externe sleutel filtert, is deze nog steeds nodig in Joins. De uitzonderingen hierop lijken nogal gekunsteld:
-
Als de selectiviteit van de refererende sleutel erg laag is, b.v. in het bovenstaande scenario, als 50% van ALLE steden in de landentabel in Japan zou zijn, dan zou de Index niet nuttig zijn.
-
Als je eigenlijk nooit door de relatie navigeert.
-
Als u nooit rijen uit de bovenliggende tabel verwijdert (of probeert bij te werken op de PK) .
Een aanvullende overweging voor optimalisatie is of de externe sleutel in de Clustered Index
moet worden gebruikt van de onderliggende tabel (d.w.z. cluster Steden per land). Dit is vaak gunstig in parent:child-tabelrelaties waar het gebruikelijk is om alle onderliggende rijen voor de parent tegelijkertijd op te halen.