Muss ich unter Oracle Indizes für Fremdschlüssel erstellen?

120

Ich habe einen Tisch Aund einen Tisch B. Ahat einen Fremdschlüssel für den Primärschlüssel von Bon B, B_ID.

Aus irgendeinem Grund (ich weiß, dass es legitime Gründe gibt) wird kein Index verwendet, wenn ich diese beiden Tabellen auf dem Schlüssel verbinde.

Muss ich separat einen Index erstellen A.B_IDoder sollte das Vorhandensein eines Fremdschlüssels dies ermöglichen?

Aw grob
quelle

Antworten:

136

Die Fremdschlüsseleinschränkung allein liefert nicht den Index für Oracle - man muss (und sollte) erstellt werden.

DCookie
quelle
11
Auf einigen Datenbanken, die eine Fremdschlüsseleinschränkung erstellen, wird auch ein Index erstellt ... dh Jet Engine (MSAccess-Dateien, Firebird und MySQL)
bubi
17
Diese Antwort ist bedeutungslos, ohne explizit auf eine bestimmte Datenbankimplementierung zu verweisen. Sicher, die Frage ist markiert, oracleaber das ist nicht sofort offensichtlich, wenn Sie über eine Google-Suche hier landen.
Developerbmw
5
Ich kann bestätigen, dass PostgreSQL - zumindest zum Zeitpunkt dieses Beitrags - dies nicht automatisch tut.
Der Dembinski
Gleiche Antwort für SQL Server (2016, Azure ...), soweit ich weiß.
Pac0
Warum muss man mit Oracle einen Index für einen Fremdschlüssel erstellen? Was sind die Konsequenzen, wenn Sie dies nicht tun?
ô Công Bằng
46

Durch das Erstellen eines Fremdschlüssels wird nicht automatisch ein Index für A.B_ID erstellt. Aus Sicht der Abfrageleistung wäre es daher im Allgemeinen sinnvoll, einen separaten Index für A.B_ID zu erstellen.

Wenn Sie jemals Zeilen in B löschen, möchten Sie auf jeden Fall, dass A.B_ID indiziert wird. Andernfalls muss Oracle jedes Mal, wenn Sie eine Zeile aus B löschen, einen vollständigen Tabellenscan für A durchführen, um sicherzustellen, dass keine verwaisten Datensätze vorhanden sind (abhängig von der Oracle-Version kann dies auch zusätzliche Auswirkungen auf die Sperrung haben, diese werden jedoch verringert in neueren Oracle-Versionen).

Justin Cave
quelle
1
Was ist mit PFK-Spalten? Wenn ich beispielsweise eine Zwischentabelle für eine Viele-zu-Viele-Beziehung habe, soll ich einen Index für die beiden PFK-Spalten dieser Tabelle erstellen?
Clamari
3
@Clamari - Wenn C den Primärschlüssel (A_ID, B_ID) hat, sorgt der Primärschlüssel dafür, dass er aus A gelöscht werden kann. Wenn Sie auch effizient aus B löschen möchten, möchten Sie einen Index für B_ID.
Justin Cave
25

Nur für weitere Informationen: Oracle erstellt keinen Index automatisch (wie bei eindeutigen Einschränkungen), da (a) die Einschränkung nicht erzwungen werden muss und (b) in einigen Fällen keine erforderlich ist.

Meistens möchten Sie jedoch einen Index erstellen (tatsächlich gibt es in Oracle Apex einen Bericht über "nicht indizierte Fremdschlüssel").

Immer wenn die Anwendung in der Lage sein muss, eine Zeile in der übergeordneten Tabelle zu löschen oder den PK-Wert (der seltener ist) zu aktualisieren, leidet die DML, wenn kein Index vorhanden ist, da die gesamte untergeordnete Tabelle gesperrt werden muss.

In einem Fall, in dem ich normalerweise keinen Index hinzufüge, befindet sich die FK in einer Tabelle mit "statischen Daten", die die Domäne einer Spalte definiert (z. B. eine Tabelle mit Statuscodes), in der Aktualisierungen und Löschungen in der übergeordneten Tabelle niemals durchgeführt werden direkt von der Anwendung. Wenn das Hinzufügen eines Index zu der Spalte jedoch wichtige Abfragen in der Anwendung unterstützt, ist der Index dennoch eine gute Idee.

Jeffrey Kemp
quelle
14

SQL Server hat noch nie automatisch Indizes für Fremdschlüsselspalten erstellt. Lesen Sie Kim Tripps hervorragenden Blogbeitrag über den Hintergrund und die Geschichte dieses urbanen Mythos.

Normalerweise ist es jedoch eine gute Idee, Ihre Fremdschlüsselspalten zu indizieren. Ja, ich würde empfehlen, sicherzustellen, dass jede FK-Spalte durch einen Index gesichert ist. nicht unbedingt nur für diese eine Spalte - vielleicht kann es sinnvoll sein, einen Index für zwei oder drei Spalten mit der FK-Spalte als erster darin zu erstellen. Hängt von Ihrem Szenario und Ihren Daten ab.

marc_s
quelle
8

Aus Leistungsgründen sollte ein Index erstellt werden. Wird bei Löschvorgängen in der Primärtabelle verwendet (um zu überprüfen, ob der zu löschende Datensatz nicht verwendet wird) und bei Verknüpfungen, bei denen normalerweise ein Fremdschlüssel beteiligt ist. Es können nur wenige Tabellen (ich erstelle sie nicht in Protokollen) vorhanden sein, die den Index nicht benötigen, aber wahrscheinlich benötigen Sie in diesen Fällen auch nicht die Fremdschlüsseleinschränkung.

ABER

Es gibt einige Datenbanken, die bereits automatisch Indizes für Fremdschlüssel erstellen. Jet Engine (Microsoft Access-Dateien) Firebird MySQL

SICHER

SQL Server Oracle

NICHT

Bubi
quelle
3
Vielen Dank für die Erwähnung, dass FIrebird SQL dies automatisch tut. Das ist genau der Punkt, den ich gesucht habe.
user424855
1

Wie bei allem, was mit der Leistung zu tun hat, hängt es von vielen Faktoren ab, und es gibt keine Silberkugel, z. B. in einer Umgebung mit sehr hoher Aktivität kann die Aufrechterhaltung eines Index inakzeptabel sein.

Am wichtigsten scheint hier die Selektivität zu sein: Wenn die Werte im Index stark dupliziert werden, kann dies zu einer besseren Leistung führen, wenn der Index gelöscht wird (falls möglich) und ein Tabellenscan ermöglicht wird.

eines Tages, wenn
quelle
1

UNIQUE-, PRIMARY KEY- und FOREIGN KEY-Einschränkungen generieren Indizes, die die Einschränkung erzwingen oder "unterstützen" (und manchmal als Hintergrundindizes bezeichnet werden). PRIMARY KEY-Einschränkungen generieren eindeutige Indizes. FOREIGN KEY-Einschränkungen generieren nicht eindeutige Indizes. UNIQUE-Einschränkungen generieren eindeutige Indizes, wenn alle Spalten nicht nullwertfähig sind, und sie generieren nicht eindeutige Indizes, wenn eine oder mehrere Spalten nullwertfähig sind. Wenn für eine Spalte oder einen Satz von Spalten die Einschränkung EINZIGARTIG, PRIMÄRTASTE oder AUSLÄNDISCHER SCHLÜSSEL festgelegt ist, müssen Sie für die Leistung keinen Index für diese Spalten erstellen.

Chinmai
quelle
Die Dokumente, mit denen Sie verlinkt haben, sind für Derby, die eingebettete Java-Datenbank, und nicht für Oracle.
Davos