2010-11-08 18 views
93

Ho un tavolo A e un tavolo B. A ha una chiave esterna a B sulla chiave primaria B, B_ID.Devo creare indici su chiavi esterne?

Per qualche motivo (so che ci sono motivi legittimi) non sta usando un indice quando mi unisco a queste due tabelle sulla chiave.

Devo creare separatamente un indice su A.B_ID o se l'esistenza di una chiave esterna lo fornisce?

risposta

109

Il solo vincolo di chiave esterna non fornisce l'indice: è necessario (e dovrebbe) essere creato.

+8

Su alcune basi di dati, creando un vincolo di chiave esterna crea anche un indice ... ie Jet Engine (file MSAccess, Firebird e MySQL) – bubi

+3

Questa risposta non ha senso senza riferimento esplicito a una particolare implementazione del database. Certo, la domanda è contrassegnata da 'oracle' ma ciò non è immediatamente ovvio quando si atterra qui da una ricerca su google. – developerbmw

+2

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

35

La creazione di una chiave esterna non crea automaticamente un indice su A.B_ID. Quindi, in genere, è logico dal punto di vista delle prestazioni dell'interrogazione creare un indice separato su A.B_ID.

Se si eliminano le righe in B, è necessario che A.B_ID sia indicizzato. In caso contrario, Oracle dovrà eseguire una scansione completa della tabella su A ogni volta che si elimina una riga da B per assicurarsi che non vi siano record orfani (a seconda della versione di Oracle, potrebbero esserci anche implicazioni di blocco aggiuntive, ma queste sono ridotte nelle versioni Oracle più recenti).

12

SQL Server non ha mai inserito automaticamente gli indici su colonne di chiavi esterne: controlla lo excellent blog post di Kim Tripp sullo sfondo e sulla storia di questo mito urbano.

In genere, è consigliabile indicizzare le colonne della chiave esterna, quindi sì, mi raccomando di assicurarmi che ogni colonna FK sia sottoposta a backup 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 la prima in là. Dipende dal tuo scenario e dai tuoi dati.

20

Solo per maggiori informazioni: Oracle non crea un indice automaticamente (come avviene per i vincoli univoci) perché (a) non è richiesto per forzare il vincolo e (b) in alcuni casi non è necessario uno.

maggior parte del tempo, però, si vuole creare un indice (in realtà, in Oracle Apex c'è un rapporto di "chiavi esterne non indicizzati").

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, poiché dovrà bloccare l'intera tabella figlio .

Un caso in cui di solito scelgo non per aggiungere un indice è dove l'FK è 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 su la tabella genitore non viene mai eseguita 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.

0

Come per qualsiasi cosa relativa alle prestazioni, dipende da molti fattori e non esiste un proiettile di silice per es. in un ambiente molto attivo, la manutenzione di un indice può essere inaccettabile.

più salienti qui sembrerebbe essere selettività: se i valori dell'indice altamente sarebbero duplicati allora può dare la migliore prestazione per eliminare l'indice (se possibile) e consentire una scansione di tabella.

3

Per motivi di prestazioni, è necessario creare un indice.Viene utilizzato nelle operazioni di eliminazione sulla tabella primaria (per verificare che il record che si sta eliminando non venga utilizzato) e nei join che di solito è implicata una chiave esterna. Solo poche tabelle (non le creo nei log) potrebbero non avere bisogno dell'indice ma probabilmente, in questo caso probabilmente non è necessario anche il vincolo di chiave esterna.

MA

ci sono alcune banche dati che già crea automaticamente indici sulle chiavi esterne. Jet Engine (file di Microsoft Access) Firebird MySQL

DI SICURO

SQL Server Oracle

non

+2

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