MySQL indicizza automaticamente le colonne di chiavi esterne?


Risposte:


229

Sì, ma solo su . Innodb è attualmente l'unico formato di tabella fornito con chiavi esterne implementate.


1
Hai qualche motivo per credere che MySQL consentirà mai le chiavi esterne su colonne non indicizzate per qualsiasi altro tipo di tabella?
Robert Gamble,

Non ho davvero potuto rispondere. Potresti cercare i motori di archiviazione Maria e Falcon che devono essere rilasciati in MySQL 6.0 e vedere se supportano le chiavi esterne su colonne non indicizzate.
Grant Limberg,

Apparentemente questo non è vero. Ho una tabella di grandi dimensioni (1 milione di record) e conto (*) dove fkey =? impiegherebbe 15 secondi. Aggiunto un indice sulla colonna fkey e ora le cose vanno al di sotto di un secondo.
AbiusX,

Stesso esperimento con un'altra tabella e 10 milioni di record. Questo è spesso MySQL 5.1 InnoDB. La tabella ha tre campi, uno è il numero intero della chiave primaria, l'altro è già indicizzato. La terza era una chiave esterna per la chiave primaria di un'altra tabella. Senza aggiungere un indice esplicito, le ricerche hanno richiesto alcuni secondi qui. Mostra indice dalla tabella inoltre non ha mostrato un indice su di esso.
AbiusX,

@AbiusX 5.1 è probabilmente troppo vecchio, vedi la risposta di MrAlexander di seguito.
e2-e4,

131

Apparentemente un indice viene creato automaticamente come specificato nel link che Robert ha pubblicato .

InnoDB richiede indici su chiavi esterne e chiavi di riferimento in modo che i controlli delle chiavi esterne possano essere veloci e non richiedere una scansione della tabella. Nella tabella di riferimento, deve esserci un indice in cui le colonne della chiave esterna sono elencate come prime colonne nello stesso ordine. Tale indice viene creato automaticamente nella tabella di riferimento se non esiste. (Ciò è in contrasto con alcune versioni precedenti, in cui gli indici dovevano essere creati in modo esplicito o la creazione di vincoli di chiave esterna avrebbe avuto esito negativo.) Nome_indice, se fornito, viene utilizzato come descritto in precedenza.

Vincoli InnoDB ed ESTERO KEY


9
+1 risposta molto migliore di quella selezionata come prova dai documenti
Gaz_Edge

6
Il testo citato non sembra più essere incluso nei documenti MySQL, il che rende poco chiaro se questo è ancora vero o no.
Courtney Miles,

7
@ user2045006 puoi fare riferimento al documento 5.0 e al documento 5.6 per il testo esatto citato
sactiw

1
Nei documenti attuali, c'è solo una leggera modifica nel testo (suppongo che il significato sia simile):InnoDB permits a foreign key to reference any index column or group of columns. However, in the referenced table, there must be an index where the referenced columns are the first columns in the same order.
Lucas Basquerotto

20

4
Questa risposta è un ottimo esempio del perché una risposta non dovrebbe mai consistere solo in un collegamento a una possibile risposta. Al momento, la pagina collegata non risponde affatto alla domanda.
Mike,

1
Aggiungi tutte le informazioni alla risposta stessa invece di pubblicare solo un link
Nico Haase

11

Non si ottiene automaticamente l'indice se si esegue ALTER TABLE (anziché CREATE TABLE), almeno in base ai documenti (il collegamento è per 5.1 ma è lo stesso per 5.5):

[...] Quando aggiungi un vincolo di chiave esterna a una tabella utilizzando ALTER TABLE, ricordati di creare prima gli indici richiesti.


2
Ho anche provato su MySQL 5.6 e MariaDB 10 e ALTER TABLE creato un indice. È interessante notare che mysqlindexcheck ha segnalato quell'indice come "indice ridondante". Ho provato a rilasciarlo ma ho riscontrato il seguente errore: "ERRORE 1553 (HY000): impossibile eliminare l'indice 'nome_indice': necessario in un vincolo di chiave esterna". Pertanto, non è possibile eliminare tale indice e conservare la chiave esterna.
Ciprian Stoica,

Potresti voler rivedere la tua risposta. MySQL crea sempre un indice per accelerare i controlli delle chiavi esterne se non ne esiste già uno . I documenti stanno provando a dirti che la creazione di indici prima dei vincoli di chiave esterna può accelerare un po 'le cose. Ad esempio, InnoDB potrebbe utilizzare un indice di chiave composita che potrebbe fungere da indice per i controlli di chiave esterna anziché generare automaticamente un indice ridondante.
BMiner

7

Per coloro che sono alla ricerca di un preventivo da 5.7 documenti :

MySQL richiede indici su chiavi esterne e chiavi di riferimento in modo che i controlli delle chiavi esterne possano essere veloci e non richiedere una scansione della tabella. Nella tabella di riferimento, deve esserci un indice in cui le colonne della chiave esterna sono elencate come prime colonne nello stesso ordine. Tale indice viene creato automaticamente nella tabella di riferimento se non esiste. Questo indice potrebbe essere eliminato silenziosamente in seguito, se si crea un altro indice che può essere utilizzato per imporre il vincolo di chiave esterna. index_name, se fornito, viene utilizzato come descritto in precedenza.


4

Come detto, per InnoDB. All'inizio ho pensato che fosse strano che molti altri (in particolare MS SQL e DB2) non lo facessero. Le scansioni di TableSpace sono migliori delle scansioni dell'indice solo in presenza di pochissime righe di tabelle, quindi per la maggior parte dei casi una chiave esterna vorrebbe essere indicizzata. Quindi mi ha colpito - questo non significa necessariamente che debba essere un indice indipendente (una colonna) - dove si trova nell'indice FK automatico di MySQL. Quindi, potrebbe essere questo il motivo per cui MS SQL, DB2 (Oracle non ne sono sicuro) ecc. Lasciano al DBA; dopo che tutti gli indici multipli su tabelle di grandi dimensioni possono causare problemi con prestazioni e spazio.


Hai sollevato un buon punto sugli indici chiave compositi; tuttavia, MySQL eliminerà automaticamente / silenziosamente un indice di chiave singola generata automaticamente se un indice di chiave composita appena creato soddisfa l'obbligo di eseguire rapidamente i controlli di chiave esterna. Ad essere sincero, non ho idea del perché MS SQL, DB2 e altri non lo facciano. Hanno poche scuse. Non riesco a pensare a un caso d'uso in cui un indice generato automaticamente su chiavi esterne sarebbe dannoso.
BMiner

2

Sì, Innodbforniscilo. Puoi inserire un nome chiave esterna dopo la FOREIGN KEYclausola o lasciarlo per consentire a MySQL di creare un nome per te. MySQL crea automaticamente un indice con il foreign_key_namenome.

CONSTRAINT constraint_name
FOREIGN KEY foreign_key_name (columns)
REFERENCES parent_table(columns)
ON DELETE action
ON UPDATE action

0

Sì, la chiave esterna dell'indice Mysql automaticamente quando si crea una tabella che ha una chiave esterna per un'altra.


-2

Non è possibile ottenere automaticamente la chiave indice

ALTER TABLE (NAME OF THE TABLE) ADD INDEX (FOREIGN KEY)

Nome della tabella creata ad esempio fotografie e CHIAVE ESTERA ad esempio photograph_id. Il codice dovrebbe essere così

ALTER TABLE photographs ADD INDEX (photograph_id);
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.