Erstellt ein Fremdschlüssel automatisch einen Index?

389

Mir wurde gesagt, dass SQL Server, wenn ich zwei Fremdschlüssel-Tabellen verwende, einen Index in der untergeordneten Tabelle erstellt. Es fällt mir schwer zu glauben, dass dies wahr ist, aber ich kann dort nicht viel herausfinden, was speziell damit zusammenhängt.

Mein eigentlicher Grund, dies zu fragen, ist, dass in einer Löschanweisung für eine Tabelle mit wahrscheinlich 15 verwandten Tabellen eine sehr langsame Antwortzeit auftritt. Ich habe unseren Datenbank-Mitarbeiter gefragt, und er sagt, wenn sich ein Fremdschlüssel in den Feldern befindet, verhält er sich wie ein Index. Wie ist Ihre Erfahrung damit? Sollte ich Indizes für alle Fremdschlüsselfelder hinzufügen oder sind sie nur unnötiger Aufwand?

Nick DeVore
quelle
Ich habe das gleiche Verständnis wie Ihr DB-Typ - dass FKs tatsächlich einen Index erstellen.
Vinnie
9
Nein - ein FK erstellt NICHT automatisch einen Index. Es ist sinnvoll, eine zu erstellen - dies wird jedoch NICHT automatisch von SQL Server durchgeführt.
marc_s
47
nicht dumm, das überhaupt zu fragen!
marc_s
5
Wenn Sie langsame Löschvorgänge erhalten und die Tabelle, aus der Sie löschen, von anderen Tabellen referenziert wird, erhalten Sie wahrscheinlich eine Leistungssteigerung, indem Sie die Fremdschlüssel in den anderen Tabellen indizieren . Dies liegt daran, dass SQL beim Löschen einer Zeile die referenzielle Integrität der Zeile überprüfen muss. Dazu muss natürlich überprüft werden, ob keine anderen Zeilen vorhanden sind, die auf die zu löschende Zeile verweisen.
Noel Kennedy
3
Ich würde sagen, ein Datenbank-Typ, der das nicht wusste, muss dringend geschult werden. Datenbankmitarbeiter sind für die Leistung verantwortlich. Es ist ihre Aufgabe, solche Dinge zu wissen. Dies deutet auf eine grobe Inkompetenz hin.
HLGEM

Antworten:

343

Ein Fremdschlüssel ist eine Einschränkung, eine Beziehung zwischen zwei Tabellen - das hat nichts mit einem Index an sich zu tun.

Es ist jedoch bekannt, dass es sehr sinnvoll ist, alle Spalten zu indizieren, die Teil einer Fremdschlüsselbeziehung sind, da Sie bei einer FK-Beziehung häufig eine zugehörige Tabelle nachschlagen und bestimmte Zeilen basierend darauf extrahieren müssen ein einzelner Wert oder ein Wertebereich.

Es ist also sinnvoll, alle an einem FK beteiligten Spalten zu indizieren, aber ein FK an sich ist kein Index.

Lesen Sie Kimberly Tripps hervorragenden Artikel "Wann hat SQL Server aufgehört, Indizes für Fremdschlüsselspalten zu erstellen?" .

marc_s
quelle
Ja. Ich bin mir ziemlich sicher, dass PostgreSQL einen Index erstellt. Ich bin mir ziemlich sicher, dass MySQL dies tut. Es macht eine Menge Sinn, den Index zu erstellen, aber es ist nicht erforderlich. Warum also auf etwas verweisen, wenn die Datenbank jedes Mal, wenn sie nachschlägt, einen Tabellenscan durchführen muss?
MBCook
Dieser oben erwähnte Artikel ist etwas verwirrend, da SQL Server oder eine andere Datenbank niemals einen Index für FK erstellt.
Vsingh
7
@vsingh: Genau das versucht der Artikel zu vermitteln - es ist ein weit verbreitetes Missverständnis, dass ein FK automatisch einen Index erstellt - das tut er nicht .
marc_s
5
@MBCook Nein, PostgreSQL erstellt nicht (zumindest in 9.2 oder einer früheren Version) automatisch einen Index auf der referenzierenden Seite einer Fremdschlüsselbeziehung, mit der definiert wurde REFERENCES. Es erstellt automatisch einen UNIQUEIndex für eine PRIMARY KEYoder eine UNIQUEEinschränkung und erfordert, dass ein UNIQUEIndex für das referenzierte Ende einer Fremdschlüsselbeziehung vorhanden ist, tut jedoch nichts automatisch für das referenzierende Ende, obwohl es oft eine gute Idee ist , einen Index selbst zu erstellen . Siehe stackoverflow.com/questions/970562/…
Craig Ringer
16
Die Verwirrung kann bestehen, weil MySQL InnoDB einen Index benötigt und automatisch erstellt, wenn Sie einen Fremdschlüssel hinzufügen - dev.mysql.com/doc/refman/5.5/en/…
humbads
42

Wow, die Antworten sind überall auf der Karte. Die Dokumentation sagt also:

Eine FOREIGN KEY-Einschränkung ist ein Kandidat für einen Index, weil:

  • Änderungen an PRIMARY KEY-Einschränkungen werden mit FOREIGN KEY-Einschränkungen in verwandten Tabellen überprüft.

  • Fremdschlüsselspalten werden häufig in Verknüpfungskriterien verwendet, wenn die Daten aus verwandten Tabellen in Abfragen kombiniert werden, indem die Spalte (n) in der FOREIGN KEY-Einschränkung einer Tabelle mit der Primär- oder eindeutigen Schlüsselspalte (n) in der anderen Tabelle abgeglichen werden. Ein Index ermöglicht es Microsoft® SQL Server ™ 2000, verwandte Daten in der Fremdschlüsseltabelle schnell zu finden. Das Erstellen dieses Index ist jedoch nicht erforderlich. Daten aus zwei verwandten Tabellen können kombiniert werden, auch wenn zwischen den Tabellen keine Einschränkungen für PRIMARY KEY oder FOREIGN KEY definiert sind. Eine Fremdschlüsselbeziehung zwischen zwei Tabellen zeigt jedoch an, dass die beiden Tabellen für die Kombination in einer Abfrage optimiert wurden, bei der die Schlüssel als verwendet werden seine Kriterien.

Es scheint also ziemlich klar zu sein (obwohl die Dokumentation etwas durcheinander ist), dass tatsächlich kein Index erstellt wird.

Yishai
quelle
5
Genau - es ist ein Kandidat für einen Index - aber es wird nicht automatisch als einer erstellt! Ganz klar, IMHO :-)
marc_s
4
Ich fand diesen Teil durcheinander: "Eine Fremdschlüsselbeziehung zwischen zwei Tabellen zeigt an, dass die beiden Tabellen für die Kombination in einer Abfrage optimiert wurden, die die Schlüssel als Kriterien verwendet." Das sollte lauten "... zwei Tabellen sollten optimiert werden ..."
Yishai
18

Nein, es gibt keinen impliziten Index für Fremdschlüsselfelder, warum sonst würde Microsoft sagen , „einen Index auf einem Fremdschlüssel zu erstellen ist oft nützlich“ . Ihr Kollege kann mit dem Primärschlüssel in dem genannten zu Tabelle mit dem Fremdschlüsselfeld in der verweisenden Tabelle verwirrend sein - Primärschlüssel hat einen impliziten Index erstellen.

Michael Borgwardt
quelle
Was ist "ein impliziter Index"? Bedeutet das nur, dass es einen ab * Baum gibt, ohne ihn zu erstellen?
Stephanie Seite
1
@Stephanie Page: Es ist ein Ausdruck, den ich gerade für diese Antwort erfunden habe, um einen Index zu bezeichnen, der automatisch erstellt wird. Wenn Sie einen Primärschlüssel deklarieren, erstellt und indiziert SQL Server diesen automatisch. Aber nicht, wenn Sie einen Fremdschlüssel deklarieren (einige andere DB-Systeme tun dies).
Michael Borgwardt
7

SQL Server erstellt automatisch Indizes für Primärschlüssel, jedoch nicht für Fremdschlüssel. Erstellen Sie den Index für die Fremdschlüssel. Es ist wahrscheinlich den Aufwand wert.

Paul Sonier
quelle
6

Angenommen, Sie haben einen großen Tisch namens Bestellungen und einen kleinen Tisch namens Kunden. Es gibt einen Fremdschlüssel von einer Bestellung an einen Kunden. Wenn Sie nun einen Kunden löschen, muss SQL Server überprüfen, ob keine verwaisten Bestellungen vorhanden sind. Wenn dies der Fall ist, wird ein Fehler ausgegeben.

Um zu überprüfen, ob Bestellungen vorliegen, muss SQL Server die Tabelle mit den großen Bestellungen durchsuchen. Wenn es nun einen Index gibt, ist die Suche schnell. Ist dies nicht der Fall, ist die Suche langsam.

In diesem Fall könnte das langsame Löschen durch das Fehlen eines Index erklärt werden. Vor allem, wenn SQL Server 15 große Tabellen ohne Index durchsuchen müsste.

PS Wenn der Fremdschlüssel ON DELETE CASCADE hat, muss SQL Server weiterhin die Auftragstabelle durchsuchen, dann aber alle Bestellungen entfernen, die auf den gelöschten Kunden verweisen.

Andomar
quelle
Genau - das ist der Grund, warum ein Index auf einem FK (meistens) sehr viel Sinn macht
marc_s
1
Meistens? Dies scheint bei einem Löschen von einem Elternteil der Fall zu sein. Wenn Sie die meiste Zeit von den Eltern löschen, denke ich, dass das stimmt.
Stephanie Seite
6

Fremdschlüssel erstellen keine Indizes. Nur alternative Schlüsseleinschränkungen (EINZIGARTIG) und Primärschlüsseleinschränkungen erstellen Indizes. Dies gilt für Oracle und SQL Server.

Sandeep Kanuri
quelle
3

Meines Wissens nicht. Ein Fremdschlüssel fügt nur die Einschränkung hinzu, dass der Wert im untergeordneten Schlüssel auch irgendwo in der übergeordneten Spalte dargestellt wird. Es sagt der Datenbank nicht, dass der untergeordnete Schlüssel auch indiziert werden muss, nur eingeschränkt.

Gandalf
quelle
3

Genau genommen haben Fremdschlüssel absolut nichts mit Indizes zu tun, ja. Aber, wie die Sprecher über mir betonten, ist es sinnvoll, einen zu erstellen, um die FK-Suche zu beschleunigen. Wenn Sie in MySQL in Ihrer FK-Deklaration keinen Index angeben, erstellt die Engine (InnoDB) diesen automatisch für Sie.

shylent
quelle
3

In PostgeSql können Sie selbst nach Indizes suchen, wenn Sie auf \ d Tabellenname klicken

Sie werden sehen, dass btree-Indizes automatisch für Spalten mit Primärschlüssel und eindeutigen Einschränkungen erstellt wurden, jedoch nicht für Spalten mit Fremdschlüsseln.

Ich denke, das beantwortet deine Frage zumindest für Postgres.

Gregor
quelle
Entschuldigung, ich habe nicht bemerkt, dass die Frage MS SQL Server betrifft, aber nachdem ich die Antwort gepostet habe. Es könnte wahrscheinlich noch jemandem helfen ...
Gregor
2

Ich stelle fest, dass Entity Framework 6.1, auf das MSSQL verweist, automatisch Indizes für Fremdschlüssel hinzufügt.

Luke Puplett
quelle
Ich glaube nicht, dass dies der Fall ist, wenn Sie die Spalte manuell als Teil eines Index kennzeichnen (z. B. wenn Sie einen zusammengesetzten Index über mehrere Mitglieder erstellen)
Rowland Shaw
0

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.

Talha F.
quelle