Devo creare indici su chiavi esterne su Oracle?


120

Ho un tavolo Ae un tavolo B. Aha una chiave esterna per Bil Bchiave primaria 's, B_ID.

Per qualche ragione (so che ci sono ragioni legittime) non sta usando un indice quando unisco queste due tabelle sulla chiave.

Devo creare separatamente un indice A.B_IDo l'esistenza di una chiave esterna lo dovrebbe fornire?

Risposte:


137

Il vincolo della chiave esterna da solo non fornisce l'indice su Oracle: uno deve (e dovrebbe) essere creato.


11
Su alcuni database la creazione di un vincolo di chiave esterna crea anche un indice ... cioè Jet Engine (file MSAccess, Firebird e MySQL)
bubi

17
Questa risposta è priva di significato senza fare esplicito riferimento a una particolare implementazione del database. Sicuramente la domanda è contrassegnata oraclema non è immediatamente ovvio quando arrivi qui da una ricerca su Google.
Developerbmw

5
Posso confermare che PostgreSQL - almeno al momento di questo post - non lo fa automaticamente.
The Dembinski

Stessa risposta per SQL Server (2016, Azure ...), per quanto ne so.
Pac0

Perché è necessario creare un indice su una chiave esterna con Oracle? Quali sono le conseguenze di non farlo, per favore?
Đỗ Công Bằng

46

La creazione di una chiave esterna non crea automaticamente un indice su A.B_ID. Quindi in genere avrebbe senso dal punto di vista delle prestazioni delle query creare un indice separato su A.B_ID.

Se elimini righe in B, vuoi assolutamente che A.B_ID venga indicizzato. Altrimenti, Oracle dovrà eseguire una scansione completa della tabella su A ogni volta che si elimina una riga da B per assicurarsi che non ci siano record orfani (a seconda della versione Oracle, potrebbero esserci anche ulteriori implicazioni di blocco, ma quelle sono diminuite nelle versioni Oracle più recenti).


1
E le colonne PFK? ad esempio se ho una tabella intermedia per una relazione molti-a-molti, sholud creo un indice per le due colonne PFK di questa tabella?
Clamari

3
@Clamari - Se C ha una chiave primaria di (A_ID, B_ID), la chiave primaria si occuperà di poter eliminare da A. Se vuoi anche essere in grado di eliminare da B in modo efficiente, vorresti un indice attivo B_ID.
Justin Cave,

25

Solo per maggiori informazioni: Oracle non crea automaticamente un indice (come fa per i vincoli univoci) perché (a) non è necessario per applicare il vincolo e (b) in alcuni casi non ne hai bisogno.

Maggior parte delle volte, tuttavia, vorrai creare un indice (infatti, in Oracle Apex c'è un report di "chiavi esterne non indicizzate").

Ogni volta che l'applicazione deve essere in grado di eliminare una riga nella tabella padre o aggiornare il valore PK (che è più raro), il DML ne risentirà se non esiste alcun indice, perché dovrà bloccare l'intera tabella figlia.

Un caso in cui di solito scelgo di non aggiungere un indice è dove FK è a una tabella "dati statici" che definisce il dominio di una colonna (ad esempio una tabella di codici di stato), dove gli aggiornamenti e le eliminazioni sulla tabella genitore non vengono mai eseguiti direttamente dall'applicazione. Tuttavia, se l'aggiunta di un indice sulla colonna offre vantaggi a query importanti nell'applicazione, l'indice sarà comunque una buona idea.


14

SQL Server non ha mai inserito automaticamente gli indici nelle colonne di chiavi esterne: controlla l' eccellente post del blog di Kim Tripp sullo sfondo e la storia di questo mito urbano.

Di solito è una buona idea indicizzare le colonne delle chiavi esterne, quindi sì, consiglierei di assicurarti che ogni colonna FK sia supportata da un indice; non necessariamente su quella sola colonna - forse può avere senso creare un indice su due o tre colonne con la colonna FK come prima. Dipende dal tuo scenario e dai tuoi dati.


8

Per motivi di prestazioni è necessario creare un indice. Viene utilizzato nelle operazioni di cancellazione sulla tabella primaria (per verificare che il record che si sta cancellando non venga utilizzato) e nei join che di solito è coinvolta una chiave esterna. Solo poche tabelle (non le creo nei log) potrebbero essere che non necessitano dell'indice ma probabilmente, in questi casi probabilmente non è necessario anche il vincolo della chiave esterna.

MA

Esistono alcuni database che creano già automaticamente indici su chiavi esterne. Jet Engine (file di Microsoft Access) Firebird MySQL

DI SICURO

SQL Server Oracle

NON


3
Grazie per aver detto che FIrebird SQL lo fa automaticamente. Questo è esattamente il punto che stavo cercando.
user424855

1

Come per qualsiasi cosa relativa alle prestazioni, dipende da molti fattori e non esiste un punto debole, ad esempio in un ambiente molto attivo il mantenimento di un indice può essere inaccettabile.

La cosa più saliente qui sembrerebbe essere la selettività: se i valori nell'indice fossero altamente duplicati, potrebbe dare prestazioni migliori eliminare l'indice (se possibile) e consentire una scansione della tabella.


1

I vincoli UNIQUE, PRIMARY KEY e FOREIGN KEY generano indici che applicano o "sostengono" il vincolo (e sono talvolta chiamati indici di supporto). I vincoli PRIMARY KEY generano indici univoci. I vincoli FOREIGN KEY generano indici non univoci. I vincoli UNIQUE generano indici univoci se tutte le colonne sono non annullabili e generano indici non univoci se una o più colonne sono annullabili. Pertanto, se una colonna o un insieme di colonne ha un vincolo UNIQUE, PRIMARY KEY o FOREIGN KEY, non è necessario creare un indice su tali colonne per le prestazioni.



I documenti a cui ti sei collegato sono per Derby, il database Java incorporato, non per Oracle.
Davos
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.