it-swarm.com.de

Viele Spalten gegen wenige Tabellen - leistungsmäßig

Ja, mir ist bewusst, dass die Datennormalisierung meine Priorität sein sollte (so wie sie ist).

  1. Ich habe eine Tabelle mit 65 Spalten, in der Fahrzeugdaten mit folgenden Spalten gespeichert sind: used_vehicle, color, doors, mileage, price usw. insgesamt 65.
  2. Jetzt kann ich das teilen und habe eine Vehicle Tabelle, VehicleInterior, VehicleExterior, VehicleTechnical, VehicleExtra (alles eins zu eins eine mit der Haupttabelle Vehicle).

Nehmen wir an, ich habe ungefähr 5 Millionen Reihen (Fahrzeuge).

Bei SELECT mit einer WHERE -Klausel: Wird die Leistung besser durchsucht (beide Fälle sind zumindest bei IDs indiziert):

  1. Vehicle Tabelle mit 65 Spalten oder
  2. Vehicle Tabelle mit JOINS in vier anderen Tabellen (alle mit 5 Millionen Zeilen), um alle Daten zurückzugeben, die sich auf Vehicle beziehen?

(Berücksichtigen Sie gemäß Datenbankmodul PostgreSQL und/oder MySQL).

Schätzen Sie wirklich detaillierte Erkenntnisse, die Sie aus Ihren bisherigen Erfahrungen haben könnten?

12
Urim Kurtishi

Angenommen, es handelt sich um 1: 1-Beziehungen zwischen allen Tabellen.

Insgesamt Speicher ist praktisch immer (wesentlich) billiger mit einer einzelnen Tabelle anstelle mehrerer Tabellen in 1: 1-Beziehung. Jede Zeile hat einen Overhead von 28 Bytes sowie normalerweise ein paar Bytes mehr für zusätzliches Auffüllen. Und Sie müssen die PK-Spalte mit jeder Tabelle speichern. Und haben Sie einen separaten (redundanten) Index für jede dieser Spalten ... Größe ist wichtig für die Leistung.

Dies gilt sogar, wenn viele Spalten in den meisten Zeilen NULL sind, da NULL-Speicher sehr billig ist:

Beim Abrufen aller Spalten ist eine einzelne Tabelle wesentlich schneller als 5 miteinander verbundene Tabellen. Es ist auch viel einfacher. Das Verknüpfen von fünf Tabellen kann schwierig sein, wenn nicht alle Zeilen in allen Tabellen vorhanden sind. Mit WHERE Bedingungen, die auf eine einzelne Tabelle abzielen, ist es einfach genug, andere Tabellen mit LEFT JOIN Anzuhängen. Nicht so trivial, wenn Sie Prädikate für mehrere Tabellen haben ...

Vertikale Partitionierung may Verbessert immer noch die Leistung bestimmter Abfragen. Wenn beispielsweise 90% Ihrer Abfragen dieselben 5 von 65 verfügbaren Spalten abrufen, ist dies schneller, wenn eine Tabelle nur diese 5 Spalten enthält.

OTOH, möglicherweise können Sie solche Abfragen in einigen ausgewählten Spalten mit einem "abdeckenden" Index bearbeiten, der Nur-Index-Scans zulässt.

Ein weiterer Kandidat für die vertikale Partitionierung: Wenn Sie viele Updates für nur wenige Spalten haben, während sich der Rest kaum ändert. In einem solchen Fall kann es erheblich billiger sein, Zeilen zu teilen, da Postgres für jedes Update eine neue Zeilenversion schreibt. Es gibt Ausnahmen für große Werte, die außerhalb der Zeile gespeichert werden ("TOASTed"). Mehr Details:

Es kommt wirklich auf die gesamte Situation an. Wenn Sie Zweifel haben, entscheiden Sie sich für die einfache Lösung, einen einzigen Tisch zu haben, insbesondere wenn er die Realität gut darstellt: In Ihrem Beispiel sind dies alles Attribute eines Autos und machen zusammen Sinn.

14

Eine Auswahl für eine einzelne Tabelle sollte immer schneller sein. Sobald Sie Ihr Fahrzeug gefunden haben, haben Sie bereits alle Details.

Sie verlieren jedoch die Effizienz der Normalisierung. Zum Beispiel, wenn 1 Auto viele Modelle mit unterschiedlichen Optionen hatte.

Ist das eine Referenz-Datenbank aller Autos? Oder eine Liste von Gebrauchtfahrzeugen? Gibt es viele Beispiele für dieselbe Marke/dasselbe Modell mit denselben Optionen?

Bearbeiten: Ich sollte meine Antwort als generische rdbms und nicht als postgres-spezifisch qualifizieren. Ich verweise auf @ Erwins detaillierte Antwort speziell für Postgres

0