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.
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.
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.
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.
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.7Dokumenten 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.
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.
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.
Anscheinend wird automatisch ein Index erstellt, wie in dem Link angegeben, den Robert gepostet hat .
InnoDB- und FOREIGN KEY-Einschränkungen
quelle
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.
Ja, siehe InnoDB- und FOREIGN KEY-Einschränkungen .
quelle
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):
quelle
Für diejenigen, die ein Zitat aus
5.7
Dokumenten suchen :quelle
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.
quelle
Ja,
Innodb
geben Sie dies an. Sie können einen Fremdschlüsselnamen nach derFOREIGN KEY
Klausel einfügen oder MySQL einen Namen für Sie erstellen lassen. MySQL erstellt automatisch einen Index mit demforeign_key_name
Namen.quelle
Ja, MySQL-Index-Fremdschlüssel werden automatisch erstellt, wenn Sie eine Tabelle erstellen, die einen Fremdschlüssel für einen anderen enthält.
quelle
Es ist nicht möglich, den Indexschlüssel automatisch zu verwenden
Name der Tabelle, die Sie zum Beispiel Fotos und zum Beispiel FOREIGN KEY erstellt haben
photograph_id
. Der Code sollte so seinquelle