Preciso criar índices em chaves estrangeiras no Oracle?

120

Eu tenho uma mesa Ae uma mesa B. Apossui uma chave estrangeira para Ba Bchave primária de B_ID.

Por alguma razão (eu sei que existem razões legítimas), ele não está usando um índice quando eu ingresso nessas duas tabelas na chave.

Preciso criar um índice separadamente A.B_IDou a existência de uma chave estrangeira deve fornecer isso?

aw crud
fonte

Respostas:

136

A restrição de chave estrangeira sozinha não fornece o índice no Oracle - é preciso (e deve) ser criado.

DCookie
fonte
11
Em alguns bancos de dados, criando uma restrição de chave estrangeira cria também um índice ... Jet Motor (arquivos de MSAccess, Firebird e MySQL) ou seja
bubi
17
Esta resposta não tem sentido sem se referir explicitamente a uma implementação de banco de dados específica. Claro que a pergunta está marcada, oraclemas isso não é imediatamente óbvio quando você chega aqui a partir de uma pesquisa no Google.
developerbmw
5
Posso confirmar que o PostgreSQL - pelo menos no momento desta publicação - não faz isso automaticamente.
O Dembinski
A mesma resposta para o SQL Server (2016, Azure ...), tanto quanto eu sei.
Pac0
Por que é necessário criar um índice em uma chave estrangeira com o Oracle? Quais são as consequências de não fazê-lo, por favor?
Đỗ Công Bằng
46

Criar uma chave estrangeira não cria automaticamente um índice em A.B_ID. Portanto, geralmente faria sentido do ponto de vista do desempenho da consulta criar um índice separado no A.B_ID.

Se você excluir linhas em B, definitivamente desejará que A.B_ID seja indexado. Caso contrário, o Oracle precisará fazer uma varredura completa da tabela em A toda vez que você excluir uma linha de B para garantir que não haja registros órfãos (dependendo da versão do Oracle, também poderá haver implicações adicionais de bloqueio, mas elas serão diminuídas nas versões mais recentes do Oracle).

Justin Cave
fonte
1
E as colunas PFK? por exemplo, se eu tiver uma tabela intermediária para um relacionamento muitos-para-muitos, sholud eu crio um índice para as duas colunas PFK dessa tabela?
Clamari 27/06
3
@ Clamari - Se C tiver uma chave primária de (A_ID, B_ID), a chave primária cuidará de ser capaz de excluir de A. Se você também quiser excluir de B com eficiência, deseja um índice B_ID.
Justin Cave
25

Apenas para obter mais informações: o Oracle não cria um índice automaticamente (como ocorre com restrições exclusivas) porque (a) não é necessário impor a restrição e (b) em alguns casos você não precisa de uma.

Na maioria das vezes, no entanto, você deseja criar um índice (de fato, no Oracle Apex, há um relatório de "chaves estrangeiras não indexadas").

Sempre que o aplicativo precisar excluir uma linha da tabela pai ou atualizar o valor de PK (que é mais raro), o DML sofrerá se nenhum índice existir, pois precisará bloquear a tabela filho inteira.

Um caso em que geralmente escolho não adicionar um índice é onde o FK está em uma tabela "dados estáticos" que define o domínio de uma coluna (por exemplo, uma tabela de códigos de status), onde as atualizações e exclusões na tabela pai nunca são feitas diretamente pelo aplicativo. No entanto, se adicionar um índice à coluna forneça benefícios para consultas importantes no aplicativo, o índice ainda será uma boa ideia.

Jeffrey Kemp
fonte
14

O SQL Server nunca colocou índices em colunas de chave estrangeira automaticamente - confira a excelente postagem de blog de Kim Tripp sobre os antecedentes e a história desse mito urbano.

No entanto, geralmente é uma boa ideia indexar suas colunas de chave estrangeira - então, sim, eu recomendaria garantir que cada coluna do FK fosse copiada por um índice; não necessariamente apenas nessa coluna - talvez faça sentido criar um índice em duas ou três colunas com a coluna FK como a primeira. Depende do seu cenário e dos seus dados.

marc_s
fonte
8

Por razões de desempenho, um índice deve ser criado. É usado em operações de exclusão na tabela principal (para verificar se o registro que você está excluindo não está sendo usado) e nas junções em que geralmente uma chave estrangeira está envolvida. Apenas poucas tabelas (não as crio nos logs) podem ser as que não precisam do índice, mas provavelmente, nesses casos, provavelmente você também não precisa da restrição de chave estrangeira.

MAS

Existem alguns bancos de dados que já criam índices automaticamente em chaves estrangeiras. Jet Engine (arquivos do Microsoft Access) Firebird MySQL

COM CERTEZA

SQL Server Oracle

NÃO

bubi
fonte
3
Agradecemos por mencionar que o FIrebird SQL faz isso automaticamente. Esse é exatamente o ponto que eu estava procurando.
user424855
1

Como em qualquer coisa relacionada ao desempenho, isso depende de muitos fatores e não existe uma bala de prata, por exemplo, em um ambiente de atividade muito alto, a manutenção de um índice pode ser inaceitável.

O mais saliente aqui parece ser a seletividade: se os valores no índice forem altamente duplicados, poderá oferecer melhor desempenho para eliminar o índice (se possível) e permitir uma varredura de tabela.

um dia quando
fonte
1

As restrições UNIQUE, PRIMARY KEY e FOREIGN KEY geram índices que reforçam ou "devolvem" a restrição (e às vezes são chamados de índices de backup). As restrições PRIMARY KEY geram índices exclusivos. As restrições FOREIGN KEY geram índices não exclusivos. Restrições UNIQUE geram índices exclusivos se todas as colunas não forem anuláveis ​​e geram índices não exclusivos se uma ou mais colunas são anuláveis. Portanto, se uma coluna ou conjunto de colunas tiver uma restrição UNIQUE, PRIMARY KEY ou FOREIGN KEY, não será necessário criar um índice nessas colunas para desempenho.

Chinmai
fonte
Os documentos aos quais você vinculou são para o Derby, o banco de dados Java incorporado, não para o Oracle.
Davos