Indiziert MySQL Fremdschlüsselspalten automatisch?

261

Indiziert MySQL Fremdschlüsselspalten automatisch?

Dónal
quelle

Antworten:

229

Ja, aber nur am . Innodb ist derzeit das einzige ausgelieferte Tabellenformat, in dem Fremdschlüssel implementiert sind.

Grant Limberg
quelle
1
Haben Sie Grund zu der Annahme, dass MySQL jemals Fremdschlüssel für nicht indizierte Spalten für einen anderen Tabellentyp zulässt?
Robert Gamble
Das konnte ich wirklich nicht beantworten. Möglicherweise möchten Sie die Maria- und Falcon-Speicher-Engines nachschlagen, die in MySQL 6.0 veröffentlicht werden sollen, und prüfen, ob sie Fremdschlüssel für nicht indizierte Spalten unterstützen.
Grant Limberg
Anscheinend ist das nicht wahr. Ich habe eine große Tabelle (1 Million Datensätze) und zähle (*), wobei fkey =? würde 15 Sekunden dauern. Es wurde ein Index für die fkey-Spalte hinzugefügt, und die Dinge gehen jetzt unter eine Sekunde.
AbiusX
Gleiches Experiment mit einer anderen Tabelle und 10 Millionen Datensätzen. Dies ist ofc MySQL 5.1 InnoDB. Die Tabelle enthält drei Felder, eines ist eine Primärschlüssel-Ganzzahl, das andere ist bereits indiziert. Der dritte war ein Fremdschlüssel zum Primärschlüssel einer anderen Tabelle. Ohne einen expliziten Index hinzuzufügen, dauerte die Suche hier einige Sekunden. Index aus Tabelle anzeigen zeigte auch keinen Index darauf.
AbiusX
@AbiusX 5.1 ist wahrscheinlich zu alt, siehe MrAlexanders Antwort unten.
e2-e4
131

Anscheinend wird automatisch ein Index erstellt, wie in dem Link angegeben, den Robert gepostet hat .

InnoDB benötigt Indizes für Fremdschlüssel und referenzierte Schlüssel, damit Fremdschlüsselprüfungen schnell durchgeführt werden können und kein Tabellenscan erforderlich ist. In der Referenzierungstabelle muss ein Index vorhanden sein, in dem die Fremdschlüsselspalten als erste Spalten in derselben Reihenfolge aufgeführt sind. Ein solcher Index wird automatisch für die Referenzierungstabelle erstellt, wenn er nicht vorhanden ist. (Dies steht im Gegensatz zu einigen älteren Versionen, in denen Indizes explizit erstellt werden mussten oder die Erstellung von Fremdschlüsseleinschränkungen fehlschlagen würde.) Indexname wird, falls angegeben, wie zuvor beschrieben verwendet.

InnoDB- und FOREIGN KEY-Einschränkungen

Justin Johnson
quelle
9
+1 viel bessere Antwort als die ausgewählte als Beweis aus Dokumenten
Gaz_Edge
6
Der zitierte Text scheint nicht mehr in den MySQL-Dokumenten enthalten zu sein, sodass unklar ist, ob dies noch zutrifft oder nicht.
Courtney Miles
7
@ user2045006 Sie können auf Dokument 5.0 sowie Dokument 5.6 für den genau zitierten Text
verweisen
1
In den aktuellen Dokumenten gibt es nur eine geringfügige Änderung im Text (ich nehme an, die Bedeutung ist ähnlich):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

Ja, siehe InnoDB- und FOREIGN KEY-Einschränkungen .

Robert Gamble
quelle
4
Diese Antwort ist ein gutes Beispiel dafür, warum eine Antwort niemals nur aus einem Link zu einer möglichen Antwort bestehen sollte. Derzeit beantwortet die verlinkte Seite die Frage überhaupt nicht.
Mike
1
Bitte fügen Sie alle Informationen zur Antwort selbst hinzu, anstatt nur einen Link zu veröffentlichen
Nico Haase
11

Sie erhalten den Index nicht automatisch, wenn Sie eine ALTER TABLE (anstelle von CREATE TABLE) ausführen, zumindest gemäß den Dokumenten (der Link ist für 5.1, aber für 5.5 ist er der gleiche):

[...] Wenn Sie einer Tabelle mit ALTER TABLE eine Fremdschlüsseleinschränkung hinzufügen, müssen Sie zuerst die erforderlichen Indizes erstellen.

Thomas Lundström
quelle
2
Ich habe auch MySQL 5.6 und MariaDB 10 ausprobiert und ALTER TABLE einen Index erstellt. Es ist interessant, dass mysqlindexcheck diesen Index als "redundanten Index" gemeldet hat. Ich habe versucht, es zu löschen, aber die folgende Fehlermeldung wurde angezeigt: "FEHLER 1553 (HY000): Index 'Indexname' kann nicht gelöscht werden: Wird in einer Fremdschlüsseleinschränkung benötigt". Es ist also nicht möglich, diesen Index zu löschen und den Fremdschlüssel beizubehalten.
Ciprian Stoica
Möglicherweise möchten Sie Ihre Antwort überarbeiten. MySQL erstellt immer einen Index, um die Überprüfung von Fremdschlüsseln zu beschleunigen, falls noch keiner vorhanden ist . In den Dokumenten wird versucht, Ihnen mitzuteilen, dass das Erstellen von Indizes vor Fremdschlüsseleinschränkungen die Dinge etwas beschleunigen kann. Beispielsweise könnte ein zusammengesetzter Schlüsselindex, der als Index für die Fremdschlüsselprüfungen dienen könnte, von InnoDB verwendet werden, anstatt automatisch einen redundanten Index zu generieren.
BMiner
7

Für diejenigen, die ein Zitat aus 5.7 Dokumenten suchen :

MySQL erfordert Indizes für Fremdschlüssel und referenzierte Schlüssel, damit Fremdschlüsselprüfungen schnell durchgeführt werden können und kein Tabellenscan erforderlich ist. In der Referenzierungstabelle muss ein Index vorhanden sein, in dem die Fremdschlüsselspalten als erste Spalten in derselben Reihenfolge aufgeführt sind. Ein solcher Index wird automatisch für die Referenzierungstabelle erstellt, wenn er nicht vorhanden ist. Dieser Index wird möglicherweise später stillschweigend gelöscht, wenn Sie einen anderen Index erstellen, mit dem die Fremdschlüsseleinschränkung erzwungen werden kann. Der angegebene Indexname wird, falls angegeben, wie zuvor beschrieben verwendet.

Fahmi
quelle
4

Wie gesagt für InnoDB. Zuerst fand ich es seltsam, dass viele andere (insbesondere MS SQL und DB2) dies nicht tun. TableSpace-Scans sind nur dann besser als Index-Scans, wenn nur sehr wenige Tabellenzeilen vorhanden sind. In den allermeisten Fällen möchte ein Fremdschlüssel indiziert werden. Dann hat es mich irgendwie getroffen - das bedeutet nicht unbedingt, dass es ein eigenständiger (einspaltiger) Index sein muss - wo er sich im automatischen FK-Index von MySQL befindet. Vielleicht ist dies der Grund, warum MS SQL, DB2 (Oracle, bei dem ich mir nicht sicher bin) usw. es dem DBA überlassen. Immerhin können mehrere Indizes für große Tabellen Probleme mit der Leistung und dem Speicherplatz verursachen.

Wolf5370
quelle
Sie sprechen einen guten Punkt über zusammengesetzte Schlüsselindizes an. MySQL löscht jedoch automatisch / stillschweigend einen automatisch generierten Einzelschlüsselindex, wenn ein neu erstellter zusammengesetzter Schlüsselindex die Verpflichtung erfüllt, die Fremdschlüsselprüfungen schnell durchzuführen. Um ehrlich zu sein, habe ich keine Ahnung, warum MS SQL, DB2 und andere dies nicht tun. Sie haben wenig Entschuldigung. Ich kann mir keinen Anwendungsfall vorstellen, bei dem ein automatisch generierter Index für Fremdschlüssel schädlich wäre.
BMiner
2

Ja, Innodbgeben Sie dies an. Sie können einen Fremdschlüsselnamen nach der FOREIGN KEYKlausel einfügen oder MySQL einen Namen für Sie erstellen lassen. MySQL erstellt automatisch einen Index mit dem foreign_key_nameNamen.

CONSTRAINT constraint_name
FOREIGN KEY foreign_key_name (columns)
REFERENCES parent_table(columns)
ON DELETE action
ON UPDATE action
Navrattan Yadav
quelle
0

Ja, MySQL-Index-Fremdschlüssel werden automatisch erstellt, wenn Sie eine Tabelle erstellen, die einen Fremdschlüssel für einen anderen enthält.

giapnh
quelle
-2

Es ist nicht möglich, den Indexschlüssel automatisch zu verwenden

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

Name der Tabelle, die Sie zum Beispiel Fotos und zum Beispiel FOREIGN KEY erstellt haben photograph_id. Der Code sollte so sein

ALTER TABLE photographs ADD INDEX (photograph_id);
Ali Raza
quelle