Uma chave estrangeira cria automaticamente um índice?


389

Foi-me dito que, se eu digitar duas tabelas com chave estrangeira, o SQL Server criará algo semelhante a um índice na tabela filho. Eu acho difícil acreditar que isso seja verdade, mas não consigo encontrar muita coisa relacionada especificamente a isso.

Meu verdadeiro motivo para perguntar isso é porque estamos com um tempo de resposta muito lento em uma instrução delete contra uma tabela que provavelmente possui 15 tabelas relacionadas. Perguntei ao nosso cara do banco de dados e ele diz que, se houver uma chave estrangeira nos campos, ela funcionará como um índice. Qual a sua experiência com isso? Devo adicionar índices em todos os campos de chave estrangeira ou eles são uma sobrecarga desnecessária?


Eu tenho o mesmo entendimento que o seu banco de dados - que os FKs de fato criam um índice.
Vinnie

9
Não - um FK NÃO cria automaticamente um índice. Faz sentido criar um - mas isso não é feito automaticamente pelo SQL Server.
Marc_s

47
Não é bobo perguntar isso!
Marc_s

5
Se você estiver recebendo exclusões lentas e a tabela da qual você está excluindo for referenciada por outras tabelas, provavelmente obterá um aumento no desempenho indexando as chaves estrangeiras nas outras tabelas. Isso ocorre porque quando o SQL está excluindo uma linha, ele precisa verificar a integridade referencial na linha. Para fazer isso, obviamente, é necessário verificar se não existem outras linhas referenciando a linha que você está excluindo.
2829 Noel Kennedy

3
Eu diria que um cara de banco de dados que não sabia disso deve estar precisando muito de treinamento. O pessoal do banco de dados é responsável pelo desempenho, é o trabalho deles conhecer esse tipo de coisa. Isso sugere grande incompetência.
719 HLGEM

Respostas:


343

Uma chave estrangeira é uma restrição, um relacionamento entre duas tabelas - que nada tem a ver com um índice em si.

Mas é um fato conhecido que faz muito sentido indexar todas as colunas que fazem parte de qualquer relacionamento de chave estrangeira, porque, por meio de um relacionamento FK, você muitas vezes precisará procurar uma tabela relacionada e extrair determinadas linhas com base em um único valor ou um intervalo de valores.

Portanto, faz sentido indexar qualquer coluna envolvida em um FK, mas um FK em si não é um índice.

Confira o excelente artigo de Kimberly Tripp "Quando o SQL Server parou de colocar índices nas colunas de chave estrangeira?" .


Sim. Estou certo de que o PostgreSQL cria um índice. Eu tenho certeza que o MySQL faz. Fazer o índice faz muito sentido, mas NÃO É NECESSÁRIO. Afinal, por que fazer referência a algo se toda vez que o banco de dados procura, ele precisa fazer uma varredura de tabela?
MBCook

Este artigo mencionado acima é meio confuso porque o servidor SQL ou qualquer outro banco de dados nunca coloca um índice no FK.
vsingh

7
@vsingh: é exatamente isso que o artigo tenta transmitir - é um equívoco comum que um FK cria automaticamente um índice - não faz isso.
97811 Marc

5
@MBCook Não, o PostgreSQL não (pelo menos na versão 9.2 ou em qualquer versão anterior) cria automaticamente um índice no lado de referência de um relacionamento de chave estrangeira definido com REFERENCES. Ele cria automaticamente um UNIQUEíndice para uma PRIMARY KEYou UNIQUErestrição e exige que um UNIQUEíndice esteja presente para o final referenciado de um relacionamento de chave estrangeira, mas não faz nada automaticamente para o final do referenciamento , embora seja uma boa ideia criar um você mesmo. Veja stackoverflow.com/questions/970562/…
Craig Ringer

16
A confusão pode existir porque o MySQL InnoDB exige e cria automaticamente um índice quando você adiciona uma chave estrangeira - dev.mysql.com/doc/refman/5.5/en/…
humbads

42

Uau, as respostas estão por todo o mapa. Então a documentação diz:

Uma restrição FOREIGN KEY é candidata a um índice porque:

  • As alterações nas restrições PRIMARY KEY são verificadas com as restrições FOREIGN KEY nas tabelas relacionadas.

  • As colunas de chave estrangeira são frequentemente usadas nos critérios de junção quando os dados das tabelas relacionadas são combinados nas consultas, correspondendo as colunas na restrição FOREIGN KEY de uma tabela com as colunas de chave primária ou exclusiva na outra tabela. Um índice permite que o Microsoft® SQL Server ™ 2000 encontre dados relacionados na tabela de chaves estrangeiras rapidamente. No entanto, a criação deste índice não é um requisito. Os dados de duas tabelas relacionadas podem ser combinados, mesmo que nenhuma restrição PRIMARY KEY ou FOREIGN KEY seja definida entre as tabelas, mas um relacionamento de chave estrangeira entre duas tabelas indica que as duas tabelas foram otimizadas para serem combinadas em uma consulta que usa as chaves como seus critérios.

Portanto, parece bastante claro (embora a documentação esteja um pouco confusa) que na verdade não cria um índice.


5
Exatamente - é um CANDIDATO a um índice - mas não é criado automaticamente como um! Bem claro na verdade, IMHO :-)
marc_s

4
Eu achei essa parte confusa: "um relacionamento de chave estrangeira entre duas tabelas indica que as duas tabelas foram otimizadas para serem combinadas em uma consulta que usa as chaves como critério". Isso deve ler "... duas tabelas devem ser otimizados ..."
Yishai

18

Não, não há índice implícito nos campos de chave estrangeira; caso contrário, por que a Microsoft diria "Criar um índice em uma chave estrangeira é geralmente útil" . Seu colega pode ser confuso o campo de chave estrangeira na tabela referindo com a chave primária nos referidos-to table - chaves primárias não criar um índice implícito.


o que é "um índice implícito"? isso apenas implica que há uma árvore * sem criá-la?
31512 Stephanie Page

11
@ Stephanie Page: É uma expressão que acabei de compensar por esta resposta para significar um índice que é criado automaticamente. Se você declarar uma chave primária, o SQL Server criará e indexará automaticamente para ela. Mas não se você declarar uma chave estrangeira (alguns outros sistemas de banco de dados o fazem).
Michael Borgwardt

7

O SQL Server cria automaticamente índices para Chaves Primárias, mas não para Chaves Estrangeiras. Crie o índice para as chaves estrangeiras. Provavelmente vale a pena.


6

Digamos que você tenha uma grande mesa chamada pedidos e uma pequena mesa chamada clientes. Há uma chave estrangeira de um pedido para um cliente. Agora, se você excluir um cliente, o Sql Server deverá verificar se não há pedidos órfãos; se houver, isso gera um erro.

Para verificar se há algum pedido, o Sql Server precisa pesquisar na tabela de grandes pedidos. Agora, se houver um índice, a pesquisa será rápida; se não houver, a pesquisa será lenta.

Portanto, nesse caso, a exclusão lenta pode ser explicada pela ausência de um índice. Especialmente se o Sql Server tiver que pesquisar 15 tabelas grandes sem um índice.

PS Se a chave estrangeira tiver ON DELETE CASCADE, o Sql Server ainda precisará pesquisar a tabela de pedidos, mas remover os pedidos que façam referência ao cliente excluído.


Exatamente - essa é a razão um índice em uma FK faz muito sentido (a maioria do tempo)
marc_s

11
A maior parte do tempo? Parece que este é o caso de uma exclusão de um pai. Se na maioria das vezes você exclui dos pais, acho que é verdade.
30512 Stephanie Página

6

Chaves estrangeiras não criam índices. Somente restrições de chave alternativas (UNIQUE) e restrições de chave primária criam índices. Isso é verdade no Oracle e SQL Server.


3

Não que eu saiba. Uma chave estrangeira apenas adiciona uma restrição de que o valor na chave filha também seja representado em algum lugar da coluna pai. Não está dizendo ao banco de dados que a chave filha também precisa ser indexada, apenas restrita.


3

A rigor, chaves estrangeiras não têm absolutamente nada a ver com índices, sim. Mas, como os oradores acima de mim apontaram, faz sentido criar um para acelerar as pesquisas de FK. De fato, no MySQL, se você não especificar um índice na sua declaração FK, o mecanismo (InnoDB) o cria automaticamente para você.


3

No PostgeSql, você pode verificar se há índices se clicar em \ d tablename

Você verá que os índices btree foram criados automaticamente em colunas com chave primária e restrições exclusivas, mas não em colunas com chaves estrangeiras.

Eu acho que isso responde à sua pergunta pelo menos para o postgres.


Desculpe, não percebi que a pergunta se refere ao MS SQL Server, mas depois de postar a resposta. Ele provavelmente poderia ainda ajudar alguém ...
Gregor

2

Percebo que o Entity Framework 6.1 apontado para o MSSQL adiciona automaticamente índices em chaves estrangeiras.


Eu não acredito que ele faz se você manualmente bandeira da coluna como parte de um índice (por exemplo, se você estiver criando um índice composto por vários membros)
Rowland Shaw

0

O InnoDB requer índices em chaves estrangeiras e chaves referenciadas para que as verificações de chaves estrangeiras possam ser rápidas e não exigir uma varredura de tabela. Na tabela de referência, deve haver um índice em que as colunas de chave estrangeira sejam listadas como as primeiras colunas na mesma ordem.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.