No EF Code First, o motivo geral pelo qual você modelaria um relacionamento de chave estrangeira é para navegabilidade entre entidades. Considere um cenário simples de
Country
e City
, com carregamento antecipado definido para a seguinte instrução LINQ:var someQuery =
db.Countries
.Include(co => co.City)
.Where(co => co.Name == "Japan")
.Select(...);
Isso resultaria em uma consulta ao longo das linhas de:
SELECT *
FROM Country co
INNER JOIN City ci
ON ci.CountryId = co.ID
WHERE co.Name = 'Japan';
Sem um índice na chave estrangeira em
City.CountryId
, o SQL precisará varrer a tabela Cities para filtrar as cidades do País durante um JOIN. O índice FK também terá benefícios de desempenho se as linhas forem excluídas da tabela pai País, pois a integridade referencial precisará detectar a presença de qualquer linha Cidade vinculada (se o FK tiver
ON CASCADE DELETE
definido ou não). TL;DR
Índices em chaves estrangeiras são recomendado , mesmo que você não filtre diretamente na chave estrangeira, ela ainda será necessária em Joins. As exceções a isso parecem ser bastante planejadas:
-
Se a seletividade da chave estrangeira for muito baixa, por ex. no cenário acima, se 50% de TODAS as cidades da tabela de países estivessem no Japão, o Índice não seria útil.
-
Se você realmente nunca navegar pelo relacionamento.
-
Se você nunca excluir linhas da tabela pai (ou tentar atualizar no PK) .
Uma consideração de otimização adicional é usar a chave estrangeira no
Clustered Index
da tabela filha (ou seja, cluster Cidades por País). Isso geralmente é benéfico em relacionamentos de tabela pai :filho, onde é comum recuperar todas as linhas filho para o pai simultaneamente.