Ja, mir ist bewusst, dass die Datennormalisierung meine Priorität sein sollte (so wie sie ist).
- Ich habe eine Tabelle mit 65 Spalten Speicherung von Fahrzeugdaten mit Spalten:
used_vehicle
,color
,doors
,mileage
,price
und so weiter, insgesamt 65. - Jetzt kann ich teilen , dass und habe
Vehicle
Tabelle,VehicleInterior
,VehicleExterior
,VehicleTechnical
,VehicleExtra
(alle eins-zu-eins mitVehicle
Haupttabelle).
Nehmen wir an, ich habe ungefähr 5 Millionen Reihen (Fahrzeuge).
Weiter SELECT
mit einer WHERE
Klausel: Wird die Leistung besser durchsucht (beide Fälle mindestens indiziert IDs
):
Vehicle
Tabelle mit 65 Spalten oderVehicle
Tabelle mitJOINS
vier weiteren Tabellen (alle mit 5 Millionen Zeilen), um alle Daten zurückzugeben, die sich aufVehicle
?
(Berücksichtigen Sie gemäß Datenbankmodul PostgreSQL und / oder MySQL).
Schätzen Sie wirklich detaillierte Erkenntnisse, die Sie aus Ihren bisherigen Erfahrungen haben könnten?
postgresql
database-design
performance
partitioning
postgresql-performance
Urim Kurtishi
quelle
quelle
VehicleInterior
, andere Abfragen , die sich mit Spalten von nurVehicleTechnical
usw. Oder wenn es viele Reihen / Fahrzeuge , die absolut keine Informationen haben über (zum Beispiel) ,VehicleExtra
so Anstelle vieler Zeilen mit vielen Nullen in einer Tabelle haben Sie Zeilen in den restlichen Tabellen und keine Zeilen inVehicleExtra
Antworten:
Angenommen, es handelt sich um 1: 1-Beziehungen zwischen allen Tabellen.
Insgesamt Lagerung ist praktisch immer ( im Wesentlichen) billiger mit einer einzigen Tabelle anstelle von mehreren 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. Unter
WHERE
Bedingungen, die auf eine einzelne Tabelle abzielen, ist es einfach genug, andere Tabellen anzuhängenLEFT JOIN
. Nicht so trivial, wenn Sie Prädikate für mehrere Tabellen haben ...Die vertikale Partitionierung kann die Leistung bestimmter Abfragen noch verbessern. 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, Sie können möglicherweise solche Abfragen in einigen ausgewählten Spalten mit einem "abdeckenden" Index bearbeiten, der nur Index-Scans ermöglicht .
Ein weiterer Kandidat für die vertikale Partitionierung: Wenn Sie nur für wenige Spalten viele Aktualisierungen 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.
quelle
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
quelle