Warum sind Joins schlecht, wenn man die Skalierbarkeit berücksichtigt?


92

Warum sind Joins schlecht oder "langsam"? Ich weiß, dass ich das mehr als einmal gehört habe. Ich habe dieses Zitat gefunden

Das Problem ist, dass Verknüpfungen relativ langsam sind, insbesondere bei sehr großen Datenmengen, und wenn sie langsam sind, ist Ihre Website langsam. Es dauert lange, bis alle diese separaten Informationen von der Festplatte entfernt und wieder zusammengefügt sind.

Quelle

Ich habe immer gedacht, dass sie schnell sind, besonders beim Nachschlagen einer PK. Warum sind sie "langsam"?

sql  join 

Antworten:


98

Bei der Skalierbarkeit geht es darum, die wiederholte Arbeit vorab zu berechnen, zu verteilen oder auf das Wesentliche zu reduzieren, um den Ressourcenverbrauch pro Arbeitseinheit zu minimieren. Um gut zu skalieren, tun Sie nichts, was Sie in Bezug auf die Lautstärke nicht benötigen, und die Dinge, die Sie tatsächlich tun, stellen Sie sicher, dass sie so effizient wie möglich ausgeführt werden.

In diesem Zusammenhang ist das Verbinden zweier separater Datenquellen natürlich relativ langsam, zumindest im Vergleich zum Nicht-Verbinden, da Sie diese Arbeit live an dem Punkt erledigen müssen, an dem der Benutzer sie anfordert.

Denken Sie jedoch daran, dass die Alternative darin besteht, überhaupt keine zwei separaten Daten mehr zu haben. Sie müssen die beiden unterschiedlichen Datenpunkte in denselben Datensatz einfügen. Sie können nicht zwei verschiedene Daten ohne Konsequenz irgendwo kombinieren, stellen Sie also sicher, dass Sie den Kompromiss verstehen.

Die gute Nachricht ist, dass moderne relationale Datenbanken gut in Joins sind. Sie sollten sich Joins mit einer guten Datenbank, die gut verwendet wird, nicht so langsam vorstellen. Es gibt eine Reihe von skalierbarkeitsfreundlichen Möglichkeiten, um rohe Verknüpfungen zu erstellen und sie viel schneller zu machen:

  • Verbinden Sie sich mit einem Ersatzschlüssel (Autonumer / Identity-Spalte) anstelle eines natürlichen Schlüssels. Dies bedeutet kleinere (und daher schnellere) Vergleiche während der Verknüpfungsoperation
  • Indizes
  • Materialisierte / indizierte Ansichten (stellen Sie sich dies als vorberechneten Join oder verwaltete De-Normalisierung vor)
  • Berechnete Spalten. Sie können dies verwenden, um die Schlüsselspalten eines Joins zu hashen oder auf andere Weise vorab zu berechnen, sodass ein komplizierter Vergleich für einen Join jetzt viel kleiner und möglicherweise vorindiziert ist.
  • Tabellenpartitionen (hilft bei großen Datenmengen, indem die Last auf mehrere Festplatten verteilt wird oder wenn ein Tabellenscan auf einen Partitionsscan beschränkt wird)
  • OLAP (berechnet die Ergebnisse bestimmter Arten von Abfragen / Verknüpfungen vor. Es ist nicht ganz richtig, aber Sie können sich dies als generische Denormalisierung vorstellen.)
  • Replikation, Verfügbarkeitsgruppen, Protokollversand oder andere Mechanismen, mit denen mehrere Server Leseanfragen für dieselbe Datenbank beantworten und so Ihre Arbeitslast auf mehrere Server verteilen können.
  • Verwendung einer Caching-Ebene wie Redis, um zu vermeiden, dass Abfragen erneut ausgeführt werden, für die komplexe Verknüpfungen erforderlich sind.

Ich würde sogar sagen, dass der Hauptgrund, warum relationale Datenbanken überhaupt existieren, darin besteht, dass Sie Joins effizient durchführen können * . Es geht sicherlich nicht nur darum, strukturierte Daten zu speichern (das können Sie mit Flatfile-Konstrukten wie CSV oder XML tun). Mit einigen der von mir aufgelisteten Optionen können Sie Ihren Join sogar im Voraus vollständig erstellen, sodass die Ergebnisse bereits vor der Ausgabe der Abfrage erstellt werden - als hätten Sie die Daten denormalisiert (zugegebenermaßen auf Kosten langsamerer Schreibvorgänge).

Wenn Sie einen langsamen Join haben, verwenden Sie Ihre Datenbank wahrscheinlich nicht richtig.

Eine De-Normalisierung sollte erst durchgeführt werden, nachdem diese anderen Techniken fehlgeschlagen sind. Und die einzige Möglichkeit, "Misserfolg" wirklich zu beurteilen, besteht darin, sinnvolle Leistungsziele festzulegen und an diesen Zielen zu messen. Wenn Sie nicht gemessen haben, ist es zu früh, um überhaupt an eine De-Normalisierung zu denken.

* Das heißt, existieren als Entitäten, die sich von bloßen Sammlungen von Tabellen unterscheiden. Ein weiterer Grund für eine echte rdbms ist der sichere gleichzeitige Zugriff.


14
Indizes sollten wahrscheinlich ganz oben auf der Liste stehen. Viele ( Husten- ) Entwickler scheinen sie beim Testen eines kleinen Datensatzes zu vergessen und die Datenbank dann in der Produktion in die Knie zu zwingen. Ich habe Abfragen gesehen, die in der Größenordnung von 100.000 Mal schneller ausgeführt werden, indem einfach Indizes hinzugefügt wurden. Und das sind willkürliche Indizes, ohne eine eingehende Datenanalyse durchzuführen, um die beste Mischung für die Präfixübereinstimmung ganz links zu ermitteln.
Duncan

Ich glaube, ich habe die richtige Reihenfolge - es ist nur so, dass die meisten Entwickler bereits das erste Element ausführen, und daher sind Indizes das erste Element, bei dem sie Änderungen vornehmen müssen.
Joel Coehoorn

In Ihrem dritten Artikel erwähnen Sie "Materialisierte / indizierte Ansichten". Sprechen Sie über reguläre SQL-Ansichten oder etwas anderes?
Slolife

@slolife reguläre SQL-Ansichten entsprechen dem Ausführen einer zusätzlichen Abfrage im Hintergrund im laufenden Betrieb, wenn Sie eine Abfrage verwenden, die auf die Ansicht verweist. Sie können SQL Server aber auch anweisen, einige Ansichten zu "materialisieren". Wenn Sie dies tun, behält der SQL Server wie eine normale Tabelle eine zusätzliche Kopie der Ansichtsdaten bei, sodass diese Abfrage beim Verweisen auf die Ansicht in einer Abfrage nicht mehr im Hintergrund ausgeführt werden muss, da die Daten bereits vorhanden sind . Sie können der Ansicht auch andere Indizes als die Quelltabelle hinzufügen, um die Leistung weiter zu optimieren.
Joel Coehoorn

Danke Joel. Ich muss das untersuchen.
Slolife

29

Verknüpfungen können langsamer sein als das Vermeiden durch De-Normalisierung, aber bei korrekter Verwendung (Verbinden von Spalten mit geeigneten Indizes usw.) sind sie nicht von Natur aus langsam .

Die De-Normalisierung ist eine von vielen Optimierungstechniken, die Sie in Betracht ziehen können, wenn Ihr gut gestaltetes Datenbankschema Leistungsprobleme aufweist.


2
... außer in MySQL, das anscheinend Leistungsprobleme mit einer großen Anzahl von Joins hat, unabhängig davon, wie Ihre Indizes aussehen. Oder zumindest in der Vergangenheit.
Powerlord

2
Wenn bekannte Probleme mit dem spezifischen DBMS (und möglicherweise sogar der Version) bekannt sind, ist dieser Rat möglicherweise sinnvoll, aber als allgemeiner Rat ist er ziemlich irreführend, wenn Sie eine relationale Datenbank verwenden. Die nicht relationalen Speichermechanismen werden immer beliebter Amazon SimpleDB und CouchDB ( couchdb.apache.org ) sind Beispiele. Wenn Sie besser bedient werden, indem Sie das relationale Modell hinter sich lassen, sollten Sie wahrscheinlich auch die Produkte zurücklassen, die für das Zurück optimiert sind, und nach anderen Tools suchen.
Tendayi Mawushe

13

Artikel sagt, dass sie im Vergleich zum Fehlen von Verknüpfungen langsam sind. Dies kann durch Denormalisierung erreicht werden. Es gibt also einen Kompromiss zwischen Geschwindigkeit und Normalisierung. Vergessen Sie auch nicht die vorzeitige Optimierung :)


Auch wenn dies keine harte Regel ist, verwendet mysql möglicherweise einen Index, um diesen Join auszuführen, wenn Sie einer Tabelle beitreten. Dieser Index-Join kann viele Zeilen und einen anderen Index für jede where-Klausel in den Tabellen bereinigen. Wenn Sie nicht beitreten, verwendet MySQL normalerweise nur einen Index (der möglicherweise nicht der effizienteste ist), unabhängig davon, wie Ihre where-Klausel gebildet wird.
Leeeroy

11

Zuallererst besteht die Existenzberechtigung einer relationalen Datenbank darin, Beziehungen zwischen Entitäten modellieren zu können. Verknüpfungen sind einfach die Mechanismen, mit denen wir diese Beziehungen durchlaufen. Sie sind sicherlich mit nominalen Kosten verbunden, aber ohne Joins gibt es wirklich keinen Grund, eine relationale Datenbank zu haben.

In der akademischen Welt lernen wir Dinge wie die verschiedenen normalen Formen (1., 2., 3., Boyce-Codd usw.) und wir lernen verschiedene Arten von Schlüsseln (primär, fremd, alternativ, einzigartig usw.) und wie Diese Dinge passen zusammen, um eine Datenbank zu entwerfen. Und wir lernen die Grundlagen von SQL sowie die Manipulation von Struktur und Daten (DDL & DML).

In der Unternehmenswelt erweisen sich viele der akademischen Konstrukte als wesentlich weniger lebensfähig, als wir angenommen hatten. Ein perfektes Beispiel ist der Begriff eines Primärschlüssels. Akademisch gesehen ist es dieses Attribut (oder diese Sammlung von Attributen), das eine Zeile in der Tabelle eindeutig identifiziert. In vielen Problembereichen besteht der richtige akademische Primärschlüssel aus 3 oder 4 Attributen. Fast jeder in der modernen Unternehmenswelt verwendet jedoch eine automatisch generierte, sequentielle Ganzzahl als Primärschlüssel einer Tabelle. Warum? Zwei Gründe. Das erste ist, weil es das Modell viel sauberer macht, wenn Sie FKs überall migrieren. Die zweite und wichtigste Frage zu dieser Frage ist, dass das Abrufen von Daten über Joins mit einer einzelnen Ganzzahl schneller und effizienter ist als mit 4 Varchar-Spalten (wie bereits von einigen Leuten erwähnt).

Lassen Sie uns nun etwas tiefer in zwei spezifische Subtypen realer Datenbanken eintauchen. Der erste Typ ist eine Transaktionsdatenbank. Dies ist die Grundlage für viele E-Commerce- oder Content-Management-Anwendungen, die moderne Websites antreiben. Mit einer Transaktions-DB optimieren Sie stark in Richtung "Transaktionsdurchsatz". Die meisten Commerce- oder Content-Apps müssen die Abfrageleistung (von bestimmten Tabellen) mit der Einfügeleistung (in anderen Tabellen) in Einklang bringen, obwohl jede App ihre eigenen geschäftlichen Probleme hat, die gelöst werden müssen.

Der zweite Typ einer realen Datenbank ist eine Berichtsdatenbank. Diese werden fast ausschließlich zur Aggregation von Geschäftsdaten und zur Erstellung aussagekräftiger Geschäftsberichte verwendet. Sie sind in der Regel anders geformt als die Transaktionsdatenbanken, in denen die Daten generiert werden, und sie sind in hohem Maße für die Geschwindigkeit des Ladens von Massendaten (ETLs) und die Abfrageleistung bei großen oder komplexen Datenmengen optimiert.

In jedem Fall muss der Entwickler oder DBA sowohl die Funktions- als auch die Leistungskurven sorgfältig abwägen, und auf beiden Seiten der Gleichung gibt es viele Tricks zur Leistungssteigerung. In Oracle können Sie einen sogenannten "Erklärungsplan" ausführen, um genau zu sehen, wie eine Abfrage analysiert und ausgeführt wird. Sie möchten die ordnungsgemäße Verwendung von Indizes durch die DB maximieren. Ein wirklich unangenehmes Nein-Nein ist das Einfügen einer Funktion in die where-Klausel einer Abfrage. Wenn Sie dies tun, stellen Sie sicher, dass Oracle keine Indizes für diese bestimmte Spalte verwendet und dass im EXPLAIN-Plan wahrscheinlich ein vollständiger oder teilweiser Tabellenscan angezeigt wird. Dies ist nur ein konkretes Beispiel dafür, wie eine Abfrage geschrieben werden kann, die langsam ist und nichts mit Joins zu tun hat.

Und während es sich um Tabellenscans handelt, wirken sie sich offensichtlich proportional zur Größe der Tabelle auf die Abfragegeschwindigkeit aus. Ein vollständiger Tabellenscan von 100 Zeilen ist nicht einmal erkennbar. Führen Sie dieselbe Abfrage für eine Tabelle mit 100 Millionen Zeilen aus, und Sie müssen nächste Woche zur Rückgabe zurückkehren.

Lassen Sie uns eine Minute über Normalisierung sprechen. Dies ist ein weiteres weitgehend positives akademisches Thema, das überstrapaziert werden kann. Wenn wir über Normalisierung sprechen, meinen wir meistens die Beseitigung doppelter Daten, indem wir sie in eine eigene Tabelle einfügen und eine FK migrieren. Die Leute überspringen normalerweise die gesamte Abhängigkeitssache, die von 2NF und 3NF beschrieben wird. Und doch ist es im Extremfall durchaus möglich, eine perfekte BCNF-Datenbank zu haben, die riesig ist und gegen die man Code schreiben kann, weil sie so normalisiert ist.

Wo balancieren wir also? Es gibt keine einzige beste Antwort. Alle besseren Antworten sind in der Regel Kompromisse zwischen der einfachen Strukturpflege, der einfachen Datenpflege und der einfachen Codeerstellung / -pflege. Im Allgemeinen ist es umso besser, je weniger Daten doppelt vorhanden sind.

Warum sind Joins manchmal langsam? Manchmal ist es schlechtes relationales Design. Manchmal ist die Indizierung ineffektiv. Manchmal ist es ein Problem mit dem Datenvolumen. Manchmal ist es eine schrecklich geschriebene Anfrage.

Es tut mir leid für diese langwierige Antwort, aber ich fühlte mich gezwungen, einen fleischigeren Kontext für meine Kommentare bereitzustellen, anstatt nur eine 4-Punkte-Antwort abzurasseln.


10

Menschen mit Datenbanken mit Terrabyte-Größe verwenden immer noch Verknüpfungen. Wenn sie sie dazu bringen können, leistungsmäßig zu arbeiten, können Sie dies auch.

Es gibt viele Gründe, nicht zu denomalisieren. Erstens ist die Geschwindigkeit ausgewählter Abfragen nicht das einzige oder sogar Hauptproblem bei Datenbanken. Die Integrität der Daten ist das erste Anliegen. Wenn Sie denormalisieren, müssen Sie Techniken einsetzen, um die Daten denormalisiert zu halten, wenn sich die übergeordneten Daten ändern. Angenommen, Sie speichern den Clientnamen in allen Tabellen, anstatt sich mit der Clienttabelle auf der client_Id zu verbinden. Wenn sich nun der Name des Clients ändert (100% ige Wahrscheinlichkeit, dass sich einige Namen von Clients im Laufe der Zeit ändern), müssen Sie jetzt alle untergeordneten Datensätze aktualisieren, um diese Änderung widerzuspiegeln. Wenn Sie dies in einem Kaskaden-Update tun und über eine Million untergeordneter Datensätze verfügen, wie schnell wird dies voraussichtlich sein und wie viele Benutzer werden währenddessen unter Sperrproblemen und Verzögerungen bei ihrer Arbeit leiden? Weiter die meisten Leute, die denormalisieren, weil "

Die Denormalisierung ist ein komplexer Prozess, der ein gründliches Verständnis der Datenbankleistung und -integrität erfordert, wenn er korrekt durchgeführt werden soll. Versuchen Sie nicht zu denormalisieren, es sei denn, Sie verfügen über ein solches Fachwissen im Personal.

Joins sind ziemlich schnell genug, wenn Sie mehrere Dinge tun. Verwenden Sie zuerst einen Suggorgate-Schlüssel. Ein Int-Join ist fast immer der schnellste Join. Zweitens indizieren Sie immer den Fremdschlüssel. Verwenden Sie abgeleitete Tabellen oder Verknüpfungsbedingungen, um ein kleineres Dataset zum Filtern zu erstellen. Wenn Sie über eine große, sehr komplexe Datenbank verfügen, sollten Sie eine professionelle Datenbankperson mit Erfahrung in der Partitionierung und Verwaltung großer Datenbanken einstellen. Es gibt viele Techniken, um die Leistung zu verbessern, ohne Verknüpfungen zu entfernen.

Wenn Sie nur Abfragefunktionen benötigen, können Sie ein Datawarehouse entwerfen, das denormalisiert werden kann und über ein ETL-Tool (auf Geschwindigkeit optimiert) und nicht über die Eingabe von Benutzerdaten gefüllt wird.


8

Joins sind langsam, wenn

  • Die Daten sind nicht ordnungsgemäß indiziert
  • Ergebnisse schlecht gefiltert
  • Beitrittsabfrage schlecht geschrieben
  • Datensätze sehr groß und komplex

Je größer Ihre Datenmengen sind, desto mehr Verarbeitung benötigen Sie für eine Abfrage. Wenn Sie jedoch die ersten drei der oben genannten Optionen überprüfen und bearbeiten, erhalten Sie häufig hervorragende Ergebnisse.

Ihre Quelle gibt eine Denormalisierung als Option an. Dies ist nur in Ordnung, solange Sie bessere Alternativen ausgeschöpft haben.


7

Die Verknüpfungen können langsam sein, wenn große Teile von Datensätzen von jeder Seite gescannt werden müssen.

So was:

SELECT  SUM(transaction)
FROM    customers
JOIN    accounts
ON      account_customer = customer_id

Selbst wenn ein Index für definiert ist account_customer, müssen alle Datensätze von letzterem noch gescannt werden.

Für die Abfrageliste berücksichtigen die anständigen Optimierer wahrscheinlich nicht einmal den Indexzugriffspfad, sondern führen stattdessen ein HASH JOINoder ein MERGE JOIN.

Beachten Sie, dass für eine Abfrage wie diese:

SELECT  SUM(transaction)
FROM    customers
JOIN    accounts
ON      account_customer = customer_id
WHERE   customer_last_name = 'Stellphlug'

Der Join wird höchstwahrscheinlich schnell sein: Zuerst wird ein Index on customer_last_nameverwendet, um alle Stellphlug's zu filtern (die natürlich nicht sehr zahlreich sind), dann account_customerwird für jeden Stellphlug ein Index-Scan on ausgegeben, um seine Transaktionen zu finden.

Trotz der Tatsache, dass dies Milliarden von Datensätzen sein können accountsund customersnur wenige tatsächlich gescannt werden müssen.


aber es ist schwer zu vermeiden. Gestalten Sie Ihre App so, dass diese Art von Abfragen nicht zu oft ausgeführt wird.
Andrey

1
Wenn für die accounts(account_customer)meisten RDBMS ein Index definiert ist , wird dieser Index verwendet, um genau herauszufinden, welche Zeilen der customersDatenbank gescannt werden müssen.
Jemfinch

ja, aber es ist sowieso kein billiger betrieb. Sie können die Summe in einem Feld speichern und bei jeder Transaktion aktualisieren.
Andrey

@jemfinch: nein, werden sie nicht. Dies würde das Scannen des gesamten Index erfordern, nur um die Kunden herauszufiltern, und dann das Scannen des Kundenindex in einer verschachtelten Schleife. A HASH JOINwäre viel schneller, so dass es verwendet wird, außer in allen wichtigen Datenbanken, außer MySQLdass nur customersin einer verschachtelten Schleife geführt wird (da es kleiner ist)
Quassnoi

4

Joins are fast.Verknüpfungen sollten als Standardpraxis mit einem ordnungsgemäß normalisierten Datenbankschema betrachtet werden. Mit Verknüpfungen können Sie unterschiedliche Datengruppen auf sinnvolle Weise verbinden. Fürchte dich nicht vor dem Beitritt.

Die Einschränkung besteht darin, dass Sie die Normalisierung, das Verknüpfen und die ordnungsgemäße Verwendung von Indizes verstehen müssen.

Vorsicht vor vorzeitiger Optimierung, da der Fehler Nummer eins aller Entwicklungsprojekte die Frist einhält. Sobald Sie das Projekt abgeschlossen haben und die Kompromisse verstanden haben, können Sie die Regeln brechen, wenn Sie dies rechtfertigen können.

Es ist richtig, dass sich die Join-Leistung nicht linear verschlechtert, wenn die Größe des Datensatzes zunimmt. Daher lässt es sich nicht so gut skalieren wie einzelne Tabellenabfragen, aber es skaliert trotzdem.

Es ist auch wahr, dass ein Vogel ohne Flügel schneller fliegt, aber nur direkt nach unten.


3

Joins erfordern zusätzliche Verarbeitung, da sie mehr Dateien und Indizes suchen müssen, um die Daten miteinander zu "verbinden". "Sehr große Datenmengen" sind jedoch alle relativ. Was ist die Definition von groß? Im Fall von JOINs denke ich, dass dies ein Verweis auf eine große Ergebnismenge ist, nicht auf diesen Gesamtdatensatz.

Die meisten Datenbanken können sehr schnell eine Abfrage verarbeiten, bei der 5 Datensätze aus einer Primärtabelle ausgewählt und für jeden Datensatz 5 Datensätze aus einer zugehörigen Tabelle verknüpft werden (vorausgesetzt, die richtigen Indizes sind vorhanden). Diese Tabellen können jeweils Hunderte Millionen Datensätze oder sogar Milliarden enthalten.

Sobald Ihre Ergebnismenge wächst, werden sich die Dinge verlangsamen. Wenn die Primärtabelle im selben Beispiel 100.000 Datensätze ergibt, müssen 500.000 "verbundene" Datensätze gefunden werden. Ziehen Sie einfach so viele Daten mit zusätzlichen Verzögerungen aus der Datenbank.

Vermeiden Sie JOINs nicht, sondern wissen Sie nur, dass Sie möglicherweise optimieren / denormalisieren müssen, wenn Datasets "sehr groß" werden.


3

Auch aus dem Artikel, den Sie zitiert haben:

Viele Mega-Websites mit Milliarden von Datensätzen, Petabyte an Daten, vielen Tausenden von gleichzeitigen Benutzern und Millionen von Abfragen pro Tag verwenden ein Sharding-Schema, und einige befürworten sogar die Denormalisierung als beste Strategie für die Architektur der Datenebene.

und

Und wenn Sie keine wirklich große Website sind, müssen Sie sich wahrscheinlich keine Gedanken über diese Komplexität machen.

und

Es ist fehleranfälliger, als wenn die Datenbank all diese Arbeiten ausführt, aber Sie können über das hinaus skalieren, was selbst die Datenbanken der höchsten Preisklasse verarbeiten können.

Der Artikel diskutiert Mega-Sites wie Ebay. Bei dieser Nutzungsstufe müssen Sie wahrscheinlich etwas anderes als die einfache relationale Vanilla-Datenbankverwaltung in Betracht ziehen. Aber im "normalen" Geschäftsverlauf (Anwendungen mit Tausenden von Benutzern und Millionen von Datensätzen) sind diese teureren, fehleranfälligeren Ansätze übertrieben.


2

Verknüpfungen werden als Gegenkraft zur Skalierbarkeit angesehen, da sie normalerweise den Engpass darstellen und nicht einfach verteilt oder parallel geschaltet werden können.


Ich bin mir nicht sicher, ob das stimmt. Ich weiß, dass Teradata sicherlich in der Lage ist, Joins unter Amps zu verteilen. Offensichtlich können bestimmte Arten von Verknüpfungen schwieriger / unlösbarer sein als andere.
Cade Roux

Indizes können in RDBMS von MySQL bis Oracle partitioniert werden. AFAIK, die skaliert (verteilt ist und parallel geschaltet werden kann).
Unvernunft

2

Richtig gestaltete Tabellen mit den richtigen Angaben und korrekt geschriebenen Abfragen sind nicht immer langsam. Wo immer du das gehört hast:

Warum sind Joins schlecht oder "langsam"?

hat keine Ahnung wovon sie reden !!! Die meisten Joins werden sehr schnell sein. Wenn Sie viele, viele Zeilen gleichzeitig verbinden müssen, können Sie im Vergleich zu einer denormalisierten Tabelle einen Treffer erzielen. Dies geht jedoch auf ordnungsgemäß gestaltete Tabellen zurück. Sie müssen wissen, wann Sie denormalisieren müssen und wann nicht. Teilen Sie in einem umfangreichen Berichtssystem die Daten in denormalisierten Tabellen für Berichte auf oder erstellen Sie sogar ein Data Warehouse. In einem transaktionslastigen System normalisieren Sie die Tabellen.


1

Die Menge der temporären Daten, die generiert werden, kann basierend auf den Verknüpfungen sehr groß sein.

Zum Beispiel hatte eine Datenbank hier bei der Arbeit eine generische Suchfunktion, bei der alle Felder optional waren. Die Suchroutine hat vor Beginn der Suche eine Verknüpfung für jede Tabelle durchgeführt. Das hat am Anfang gut funktioniert. Aber jetzt, wo die Haupttabelle über 10 Millionen Zeilen hat ... nicht so sehr. Die Suche dauert jetzt 30 Minuten oder länger.

Ich wurde beauftragt, die gespeicherte Suchprozedur zu optimieren.

Das erste, was ich tat, war, wenn eines der Felder der Haupttabelle durchsucht wurde, eine Auswahl für eine temporäre Tabelle nur für diese Felder vorzunehmen. DANN habe ich alle Tabellen mit dieser temporären Tabelle verbunden, bevor ich den Rest der Suche durchgeführt habe. Suchen, bei denen eines der Haupttabellenfelder jetzt weniger als 10 Sekunden dauert.

Wenn keines der Haupttabellenfelder durchsucht wird, mache ich ähnliche Optimierungen für andere Tabellen. Wenn ich fertig war, dauert keine Suche länger als 30 Sekunden, wobei die meisten unter 10 sind.

Die CPU-Auslastung des SQL-Servers ging ebenfalls stark zurück.


@BoltBait: Ist die Nachricht zum Mitnehmen, dass Sie immer versuchen sollten, die Anzahl der Zeilen zu reduzieren, bevor Sie einen Join ausführen?
Unutbu

In meinem Fall hat es sicherlich Wunder gewirkt. Aber ich würde ein System nicht optimieren, bis es notwendig wird.
BoltBait

Normalerweise werden bei Joins keine temporären Daten generiert (abhängig von der Selektivität, dem verfügbaren Speicher und der Größe der Join-Puffer). AFAIK; Die temporären Daten werden jedoch in der Regel in der Reihenfolge von und getrennt erstellt, wenn kein Index für solche Vorgänge verwendet werden kann.
Unvernunft

1

Während Verknüpfungen (vermutlich aufgrund eines normalisierten Designs) beim Abrufen von Daten offensichtlich langsamer sein können als das Lesen aus einer einzelnen Tabelle, kann eine denormalisierte Datenbank für Datenerstellungs- / Aktualisierungsvorgänge langsam sein, da der Platzbedarf der gesamten Transaktion nicht minimal ist.

In einer normalisierten Datenbank befinden sich Daten nur an einem Ort, sodass der Platzbedarf für ein Update so gering wie möglich ist. In einer denormalisierten Datenbank ist es möglich, dass dieselbe Spalte in mehreren Zeilen oder über Tabellen hinweg aktualisiert werden muss, was bedeutet, dass der Platzbedarf größer ist und die Wahrscheinlichkeit von Sperren und Deadlocks zunimmt.


1

Ja, die Auswahl von Zeilen aus einer denormalisierten Tabelle (unter der Annahme anständiger Indizes für Ihre Abfrage) ist möglicherweise schneller als die Auswahl von Zeilen, die aus der Verknüpfung mehrerer Tabellen erstellt wurden, insbesondere wenn für die Verknüpfungen keine effizienten Indizes verfügbar sind.

Die im Artikel genannten Beispiele - Flickr und eBay - sind IMO-Ausnahmefälle und haben (und verdienen) außergewöhnliche Antworten. Der Autor weist ausdrücklich auf das Fehlen von RI und das Ausmaß der Datenvervielfältigung im Artikel hin.

Die meisten Anwendungen - wiederum IMO - profitieren von der Validierung und reduzierten Duplizierung durch RDBMS.


0

Sie können langsam sein, wenn sie schlampig gemacht werden. Wenn Sie beispielsweise bei einem Join ein 'select *' ausführen, dauert es wahrscheinlich eine Weile, bis Sie die Daten zurückbekommen. Wenn Sie jedoch sorgfältig auswählen, welche Spalten aus jeder Tabelle zurückgegeben werden sollen, und die richtigen Indizes vorhanden sind, sollte dies kein Problem darstellen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.