Verbessert der Fremdschlüssel die Abfrageleistung?

149

Angenommen, ich habe 2 Tabellen, Produkte und Produktkategorien. Beide Tabellen haben eine Beziehung zu CategoryId. Und das ist die Frage.

SELECT p.ProductId, p.Name, c.CategoryId, c.Name AS Category
FROM Products p
INNER JOIN ProductCategories c ON p.CategoryId = c.CategoryId
WHERE c.CategoryId = 1;

Wenn ich einen Ausführungsplan erstelle, führt die Tabelle ProductCategories die erwartete Clusterindexsuche durch. Bei Tabellenprodukten wird jedoch ein Cluster-Index-Scan durchgeführt, was mich zweifeln lässt. Warum hilft FK nicht, die Abfrageleistung zu verbessern?

Also muss ich einen Index für Products.CategoryId erstellen. Wenn ich den Ausführungsplan erneut erstelle, führen beide Tabellen eine Indexsuche durch. Die geschätzten Teilbaumkosten werden erheblich reduziert.

Meine Fragen sind:

  1. Hat FK neben den Hilfen bei Beziehungsbeschränkungen noch andere Vorteile? Verbessert es die Abfrageleistung?

  2. Sollte ich einen Index für alle FK-Spalten (beliebte Products.CategoryId) in allen Tabellen erstellen?

Chaowlert Chaisrichalermpol
quelle

Antworten:

186

Fremdschlüssel sind ein referenzielles Integritätswerkzeug, kein Leistungswerkzeug. Zumindest in SQL Server wird beim Erstellen eines FK kein zugeordneter Index erstellt, und Sie sollten Indizes für alle FK-Felder erstellen, um die Suchzeiten zu verbessern.

cmsjr
quelle
40
Gute Modelle schneiden (im Allgemeinen) besser ab.
Kenny Evitt
10
"Fremdschlüssel sind ein Werkzeug für relationale Integrität" - verwenden Sie das Wort "relational" mit Vorsicht. Fremdschlüssel sind ein Datenbankkonzept, eine Abkürzung für eine referenzielle Integritätsbeschränkung. Sie sind nicht Teil des relationalen Modells. Ich nehme an, Sie haben einen Tippfehler gemacht.
Tag, wenn
7
@Kenny Oft ja, aber manchmal kostet ein besseres Modell mehr. Ein typisches Beispiel: Fremdschlüssel bewirken, dass mehr und nicht weniger verarbeitet werden.
Hans
8
Fremdschlüssel tun die Leistung verbessern, zumindest in MySQL. Außerdem haben Sie Recht, bei der Erstellung eines FK wird kein Index erstellt. Die Erstellung eines FK erfordert einen Index
Félix Gagnon-Grenier
15
Diese Antwort ist ziemlich nutzlos, weil sie die Frage nicht beantwortet. Es ist toll zu wissen , dass Fremdschlüssel sind nicht beabsichtigt , eine (positive) Auswirkungen auf die Leistung zu haben, aber die Frage der Realität wurde über, nicht Absichten.
John
58

Fremdschlüssel können die Leistung verbessern (und beeinträchtigen)

  1. Wie hier angegeben: Fremdschlüssel steigern die Leistung

  2. Sie sollten immer Indizes für FK-Spalten erstellen, um Suchvorgänge zu reduzieren. SQL Server führt dies nicht automatisch aus.

Bearbeiten

Da der Link nun tot zu sein scheint (ein großes Lob an Chris, dass er es bemerkt hat) , zeigt das Folgende, warum Fremdschlüssel die Leistung verbessern (und beeinträchtigen) können.

Kann Fremdschlüssel die Leistung verbessern?

Fremdschlüsseleinschränkungen verbessern die Leistung zum Zeitpunkt des Lesens von Daten, verlangsamen jedoch gleichzeitig die Leistung zum Zeitpunkt des Einfügens / Änderns / Löschens von Daten.

Beim Lesen der Abfrage kann der Optimierer Fremdschlüsseleinschränkungen verwenden, um effizientere Abfragepläne zu erstellen, da Fremdschlüsseleinschränkungen vordeklarierte Regeln sind. Dies beinhaltet normalerweise das Überspringen eines Teils des Abfrageplans, da der Optimierer beispielsweise erkennen kann, dass es aufgrund einer Fremdschlüsseleinschränkung nicht erforderlich ist, diesen bestimmten Teil des Plans auszuführen.

Lieven Keersmaekers
quelle
3
Hier ist ein Link, der detailliert beschreibt, wie sie die Leistung beeinträchtigen
cmsjr
3
Das macht Sinn, aber Sie werden nur mit einer massiven Löschanweisung darauf stoßen. Vielleicht sollte die Schlussfolgerung sein, dass in OLAP-Umgebungen nicht indizierte FKs die Leistung verbessern würden, während sie in OLTP-Umgebungen die Leistung beeinträchtigen würden.
Lieven Keersmaekers
1
Der Link in dieser Antwort ist tot. Dies ist bedauerlich, da es hier das einzige Argument für die Verbesserung der Leistung von FKs ist.
Chris Moschini
1
@ ChrisMoschini - Ich habe Ihren Kommentar bis jetzt nicht bemerkt. Wie Sie bereits erwähnt haben, ist der Link tot, aber der Kern des Links wird in dem neuen Link (mit Details) erwähnt, den ich gepostet habe.
Lieven Keersmaekers
2
Wayback Machine Link für den Win! Der Artikel ist auch auf SQLMag.com hier zu finden .
John Eisbrener
15

Ein Fremdschlüssel ist ein DBMS-Konzept zur Gewährleistung der Datenbankintegrität.

Alle Auswirkungen / Verbesserungen auf die Leistung sind spezifisch für die verwendete Datenbanktechnologie und dem Zweck eines Fremdschlüssels untergeordnet.

In SQL Server wird empfohlen, sicherzustellen, dass alle Fremdschlüssel mindestens einen nicht gruppierten Index haben.

Ich hoffe, dies klärt die Dinge für Sie auf, aber bitte fordern Sie weitere Details an.

John Sansom
quelle
9
@Kenny Evitt Wenn Sie keine Integrität haben, sind Ihre Daten nutzlos. Ich finde, das verkauft sich sehr leicht.
HLGEM
@HLGEM Hin und wieder einen 404-Fehler zu bekommen ist immer noch ziemlich erträglich. Ein außergewöhnlicher Durchsatz im Gegenzug mit billigeren Ressourcen und weniger komplexen Systemen, der sich jetzt auch sehr leicht verkaufen lässt. Das GAP-Theorem könnte Sie interessieren .
Daniel Dinnyes
8
@ Daniel Dinnyes, bei der Datenintegrität geht es nicht darum, einen 404-Fehler zu erhalten. Es geht darum, nutzbare Daten zu haben. Es geht darum, Aufträge und Finanzdaten für Berichte nicht zu verlieren, beispielsweise aufgrund der Inkompetenz der Entwickler. Es gibt keinen Grund, keine Fremdschlüssel zu verwenden.
HLGEM
2
Ich stimme HLGEM zu. Es ist nicht immer eine gute Idee, Ihren Code mit Integrität umgehen zu lassen. Daten werden häufig verwendet, um Entscheidungen zu treffen. Wenn die Daten jedoch beschädigt sind, ist die Entscheidung nicht korrekt.
Lepe
1
"Fremdschlüssel sind ein Werkzeug für relationale Integrität" - verwenden Sie das Wort "relational" mit Vorsicht. Fremdschlüssel sind ein Datenbankkonzept, eine Abkürzung für eine referenzielle Integritätsbeschränkung. Sie sind nicht Teil des relationalen Modells. Ich nehme an, Sie haben einen Tippfehler gemacht.
Tag, wenn
4

Ihre beste Leistung besteht darin, Indizes für Felder zu verwenden, die Sie häufig verwenden. Wenn Sie SQL Server verwenden, können Sie den Profiler verwenden, um eine bestimmte Datenbank zu profilieren, die ausgegebene Datei zu übernehmen und mithilfe des Optimierungsassistenten Empfehlungen zum Platzieren Ihrer Indizes zu erhalten. Ich benutze auch gerne den Profiler, um lang laufende gespeicherte Prozeduren auszuspülen. Ich habe eine Liste der zehn schlimmsten Straftäter, die ich jede Woche veröffentliche, und halte die Leute ehrlich: D.

Al Katawazi
quelle
3

Sie können es verwenden, um eine Abfrage effizienter zu gestalten. Sie können Abfragen in SQL Server so umstrukturieren, dass anstelle eines inneren Joins ein äußerer Join verwendet wird, sodass SQL Server nicht mehr überprüft werden müssen, ob die Spalte eine Null enthält. Sie müssen dieses Qualifikationsmerkmal nicht eingeben, da die Fremdschlüsselbeziehung dies bereits für Sie erzwingt.

Also das:

    select p.ProductId, p.Name, c.CategoryId, c.Name AS Category 
from Products p inner join ProductCategories c on p.CategoryId = c.CategoryIdwhere c.CategoryId = 1;

Wird dies:

SELECT p.ProductId, p.Name, c.CategoryId, c.Name AS Category 
FROM ProductCategories c 
LEFT OUTER JOIN Products P ON
c.CategoryId = p.CategoryId 
WHERE c.CategoryId = 1;

Dies führt bei kleinen Abfragen nicht unbedingt zu einer großen Leistung, aber wenn Tabellen groß werden, kann dies effizienter sein.

kemiller2002
quelle
3
Äußere Verknüpfungen sind in der Regel nicht nur weniger effizient als innere Verknüpfungen ( stackoverflow.com/a/2726683/155892 ), sondern Ihre Abfragen sind jetzt irreführend: Sie verlassen sich auf die Datenbank, um Ihre äußeren Verknüpfungen implizit in innere Verknüpfungen umzuwandeln (Wiederherstellung der Leistung). anstatt das nur explizit zu tun
Mark Sowul
2

Für MySQL 5.7 kann es Abfragen mit mehreren Joins auf jeden Fall erstaunlich gut beschleunigen!

Ich habe 'EXPLAIN' verwendet, um meine Abfrage zu verstehen, und festgestellt, dass ich 4-5 Tabellen verknüpft habe - wobei überhaupt keine Schlüssel verwendet wurden. Ich habe diesen Tabellen nur einen Fremdschlüssel hinzugefügt, und das Ergebnis war eine Reduzierung der Ladezeit um 90%. Abfragen, die> 5 Sekunden dauerten, dauern jetzt 500 ms oder weniger.

Das ist eine enorme Verbesserung!

UND, wie andere bereits erwähnt haben, erhalten Sie den zusätzlichen Bonus, die relationale Integrität sicherzustellen.

Darüber hinaus hat die Gewährleistung der referenziellen Integrität auch eigene Leistungsvorteile. Dies hat den Effekt zweiter Ordnung, dass sichergestellt wird, dass die Tabellen mit dem Fremdschlüssel mit der Fremdtabelle auf dem neuesten Stand sind. Angenommen, Sie haben eine Benutzertabelle und eine Kommentartabelle und führen Statistiken zur Kommentartabelle durch. Wenn Sie den Benutzer schwer löschen, möchten Sie wahrscheinlich auch seine Kommentare nicht mehr.

Peter Bartlett
quelle
Hatten die Tabellen die erforderlichen Indizes, um die Fremdschlüssel zu generieren, bevor Sie sie hinzugefügt haben?
George
1

Das Hinzufügen eines Fremdschlüssels zur Tabelle verbessert die Leistung nicht. Wenn Sie lediglich einen Datensatz in eine ProductCategories-Tabellendatenbank einfügen, wird versucht, die Fremdschlüsselspalte mit einem Wert zu ermitteln, der im Primärschlüsselwert einer Produkttabelle vorhanden ist. Jedes Mal, wenn Sie einen neuen Eintrag in der ProductCategories-Tabelle hinzufügen, ist der Betrieb Ihrer Datenbank mit einem Overhead verbunden. Wenn Sie also einen Fremdschlüssel hinzufügen, wird Ihre Datenbankleistung nicht verbessert, aber die Integrität Ihrer Datenbank wird berücksichtigt. Ja, es verbessert die Leistung Ihrer Datenbank, wenn Sie die Integrität mithilfe eines Fremdschlüssels überprüfen, anstatt viele Abfragen auszuführen, um zu überprüfen, ob der Datensatz in der Datenbank Ihres Programms vorhanden ist.

Pankaj Khairnar
quelle
0

Ich weiß nicht viel über SQL Server, aber im Fall von Oracle verringert eine Fremdschlüsselspalte die Leistung beim Laden von Daten. Dies liegt daran, dass die Datenbank die Datenintegrität für jede Einfügung überprüfen muss. Und ja, wie bereits erwähnt, ist es eine gute Praxis, einen Index für die Fremdschlüsselspalte zu haben.

Shamik
quelle