In EF Code First, the general reason why you would model a foreign key relationship is for navigability between entities. Consider a simple scenario of Country
and City
, with eager loading defined for the following LINQ statement:
var someQuery =
db.Countries
.Include(co => co.City)
.Where(co => co.Name == "Japan")
.Select(...);
This would result in a query along the lines of:
SELECT *
FROM Country co
INNER JOIN City ci
ON ci.CountryId = co.ID
WHERE co.Name = 'Japan';
Without an Index on the foreign key on City.CountryId
, SQL will need to scan the Cities table in order to filter the cities for the Country during a JOIN.
The FK index will also have performance benefits if rows are deleted from the parent Country table, as referential integrity will need to detect the presence of any linked City rows (whether the FK has ON CASCADE DELETE
defined or not).
TL;DR
Indexes on Foreign Keys are recommended, even if you don't filter directly on the foreign key, it will still be needed in Joins. The exceptions to this seem to be quite contrived:
If the selectivity of the foreign key is very low, e.g. in the above scenario, if 50% of ALL cities in the countries table were in Japan, then the Index would not be useful.
If you don't actually ever navigate across the relationship.
If you never delete rows from the parent table (or attempt update on the PK) .
One additional optimization consideration is whether to use the foreign key in the Clustered Index
of the child table (i.e. cluster Cities by Country). This is often beneficial in parent : child table relationships where it is common place to retrieve all child rows for the parent simultaneously.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…