2010-04-11 14 views
14

Ich baue Ruby on Rails 2.3.5 app. Standardmäßig stellt Ruby on Rails keine Fremdschlüsselbeschränkungen bereit, daher muss ich es manuell tun. Ich habe mich gefragt, ob die Einführung von Fremdschlüsseln die Abfrageleistung auf der Datenbankseite so weit reduziert, dass es sich nicht lohnt. Leistung in diesem Fall ist meine erste Priorität, da ich auf Datenkonsistenz mit Code überprüfen kann. Was ist Ihre Empfehlung im Allgemeinen? Empfehlen Sie die Verwendung von Fremdschlüsseln? und wie schlägst du vor, ich sollte das messen?Führt die Einführung von Fremdschlüsseln in MySQL die Leistung herab

+0

Fremdschlüssel hat tatsächlich einen positiven Effekt in der Leistung in Anbetracht seiner Auswirkung auf Inter-Tabelle Select-Abfragen mit Joins. Ich bin mir nicht sicher, ob es einen negativen Effekt hat. – Hanseh

+1

Heh, drei der Top-Antworten auf diese Frage sind "Leistungsvorteil", "kein Unterschied", "Leistungsverlust". –

Antwort

15

Unter der Annahme:

  1. Sie sind bereits eine Speicher-Engine verwenden, die FKs unterstützt (zB: InnoDB)
  2. Sie haben bereits Indizes für die Spalten beteiligt

Dann würde ich vermuten, dass Sie eine bessere Leistung erhalten, indem Sie MySQL Integrität erzwingen. Die Durchsetzung der referenziellen Integrität ist schließlich etwas, auf das Datenbank-Engines optimiert sind. Das Schreiben von eigenem Code zur Verwaltung der Integrität in Ruby wird im Vergleich langsam sein.

Wenn Sie von MyISAM zu InnoDB wechseln müssen, um die FK-Funktionalität zu erhalten, müssen Sie die Leistungseinbußen zwischen den beiden Engines berücksichtigen.

Wenn Sie noch keine Indizes haben, müssen Sie entscheiden, ob Sie sie haben möchten. Im Allgemeinen, wenn Sie mehr lesen als schreiben, wollen Sie (müssen, sogar) die Indizes.

Das Stapeln eines FK über die aktuell indizierten Elemente sollte insgesamt weniger Auswirkungen auf die Performance haben als die Implementierung solcher Prüfungen in Ihrem Anwendungscode.

5

Im Allgemeinen werden mehr Tasten (fremd oder anders) die INSERT/UPDATE-Leistung verringern und die SELECT-Leistung erhöhen.

Der zusätzliche Vorteil der Datenintegrität, ist wahrscheinlich fast immer die kleine Leistungseinbuße, die mit dem Hinzufügen Ihrer Fremdschlüssel kommt. Was nützt eine schnelle App, wenn die Daten darin Junk (fehlende Teile oder etc) sind?

Gefunden eine ähnliche Abfrage hier: Does Foreign Key improve query performance?

3

Sie sollten Fremdschlüssel definieren. Im Allgemeinen (obwohl ich die Besonderheiten von mySQL nicht kenne), hat dies keine Auswirkungen auf Abfragen (und wenn es einen Optimierer gibt, wie der Cost Based Optimizer in Oracle, kann es sogar positive Auswirkungen haben, da sich der Optimierer auf die ausländische Schlüsselinformationen, um bessere Zugangspläne zu wählen). Je nach Auswirkung auf Einfügung und Aktualisierung kann es Auswirkungen haben, aber die Vorteile, die Sie erhalten (referenzielle Integrität und Datenkonsistenz), übertreffen die Auswirkungen auf die Leistung bei weitem. Natürlich können Sie ein System entwerfen, das überhaupt nicht funktioniert, aber der Hauptgrund wird nicht sein, weil Sie die Fremdschlüssel hinzugefügt haben. Und die Auswirkungen auf die Pflege Ihres Codes, wenn Sie sich für eine andere Sprache entscheiden, oder weil sich die Geschäftsregeln leicht geändert haben, oder weil ein neuer Programmierer Ihrem Team usw. beitritt, sind weitaus teurer als die Auswirkungen auf die Leistung. Meine Empfehlung lautet dann ja, geh und definiere die Fremdschlüssel. Ihr Endprodukt wird robuster sein.

1

Zwei Punkte:
1. Sind Sie sicher, dass die Integritätsprüfung auf Anwendungsebene in Bezug auf die Leistung besser wäre?
2. Führen Sie Ihren eigenen Test durch - testen, ob FKs positiven oder negativen Einfluss auf die Leistung haben, sollte fast trivial sein.

3

Es ist eine gute Idee, Fremdschlüssel zu verwenden, da dies Ihnen die Datenkonsistenz sichert (Sie wollen keine verwaisten Zeilen und andere inkonsistente Datenprobleme).

Aber gleichzeitig Hinzufügen eines Fremdschlüssels führt zu einigen Leistungseinbußen. Angenommen, Sie verwenden INNODB als Speichermodul, wird der Clustered Index für PK verwendet, bei dem im Wesentlichen Daten zusammen mit dem PK gespeichert werden. Um auf Daten zuzugreifen, die den Sekundärindex verwenden, müssen der Sekundärindexbaum (wo die Knoten die PK enthalten) und dann ein zweiter Durchlauf über den Clusterindex übergeben werden, um die Daten tatsächlich abzurufen. Jede DML in der Elterntabelle, die den betreffenden FK betrifft, erfordert daher zwei Durchläufe über den Index in der Kindtabelle. Natürlich hängt die Auswirkung des Leistungseinflusses von der Datenmenge, der Festplattenleistung und den Speicherbedingungen (Daten/Index zwischengespeichert) ab. Daher ist es am besten, es mit dem Zielsystem zu messen. Ich würde sagen, der beste Weg, um es zu messen, ist mit Ihren Beispielzieldaten oder zumindest einigen repräsentativen Zieldaten für Ihr System. Versuchen Sie dann, einige Benchmarks mit und ohne FK-Einschränkungen auszuführen. Schreiben Sie clientseitige Skripte, die in beiden Fällen die gleiche Last generieren.

Wenn Sie jedoch manuell nach FK-Einschränkungen suchen, würde ich empfehlen, dass Sie es auf mysql belassen und es von mysql verarbeiten lassen.

Verwandte Themen