Performance: Viele kleine gejointe Tabellen vs. Einige große Tabellen

Guten Tag allerseits,

in unserer Firma sind wir gerade dabei ein Datenbankmodell zu überarbeiten. Dabei ist es das Ziel von unseren vielen Tabellen und die dadurch entstandenen JOINs etwas runterzukommen. Das Ergebnis ist dann, dass man weniger Tabellen hat, dafür aber die Tabellen größer werden (mehr Felder).

Beim alten DB-Design wird eine Abfrage mit 21 JOINs benutzt. Beim neuen Design hingegen nur 8. Es werden 21 Felder ausgelesen.

Bei einem Test mit einer Kundendatenbank bin ich zu dem Ergebnis gekommen, dass das neue Datenbank-Design maximal 20% schneller ist. Die Werte schwanken aber derart stark und sind so abhängig von der SELECT-Anweisung, dass ich sehr verunsichert bin, ob die Leistung wirklich gesteigert wird. Fügt man an das SELECT noch eine WHERE-Klausel, ein ORDER BY, GROUP BY oder ähnliches an, dann kann das Ergebnis eventuell andersrum ausfallen und das alte Datenbankdesign mit den vielen JOINs ist schneller.

Folgende Faktoren beeinflussen meines Erachtens den Test:
-Rechner (Menge d. Arbeitsspeichers, Festplattengeschwindigkeit, Prozessor und Anzahl der Prozessoren).
-Welches Betriebssystem wird verwendet?
-Wann kommt der Cache zum Tragen?
-Wird die höhere Geschwindigkeit nur damit erkauft, dass der Query Analyzer stärker den PC belastet?
-Welche Datenbankversion wird benutzt?
-Welche Indizes werden benutzt?
-Wurde die Datenbankkonfiguration optimiert?
-Welche Daten liegen überhaupt vor (Wie sind die Datenmengen auf die Tabellen verteilt)?
-Sind die SELECTs vielleicht schneller, dafür aber INSERTs/DELETEs etc. langsamer?
-Spielt die Datenbankklasse (beim Test wurde PHP benutzt) eine Rolle? Hat die Klasse wieder einen eigenen Cache?
-Welche DBMS wird verwendet?
-Welcher Tabellentyp wird benutzt (bei MySQL)?
-Gibt es weitere Programme die nebenher laufen und die Datenbank stören?
-Wie verhält sich das Ganze, wenn mehrere Leute parallel darauf zugreifen?
-Was ist wartbarer? (Was neigt eher zu Anomalien?)
-usw. usw.

Naja, es gibt jedenfalls einen Rattenschwanz von Abhängigkeiten, sodass mir schlecht bei dem Gedanken wird, alle Permutationen durchzuspielen oder Dinge auf gut Glück ignorieren zu müssen.

Gibt es eine pauschale Regel, dass man sagen kann, dass viele JOINs mit vielen kleineren Tabellen langsamer sind, als wenige JOINs und stattdessen großen Tabellen? Ich habe nur mal gehört, dass eine zu starke Normalisierung leistungsmindernd sein kann und man daher eine gemäßige Denormalisierung nach der Normalisierung durchführen sollte. Dennoch bin ich mir angesichts von unklaren (und nur sehr begrenzt aussagekräftigen) Testwerten unsicher, ob diese Regel überhaupt gilt.

Wer hat Erfahrungswerte?

Mit freundlichen Grüßen
Dirk N.

In eurem Fall kann man wohl keine pauschalen Aussagen treffen, dafür sieht euer Modell (vorher wie hinterher) zu komplex aus.

Allein die Liste der Faktoren, die du dir selber aufgestellt hast, sollte dir zeigen, wie komplex das Thema ist.

Ich glaube, das man von aussen nur gezielt Aussagen treffen kann, wenn man die konkrete Anfrage sieht und Informationen zum System und der Datenbank hat.

Ansonsten wäre es für euch wohl besser, jemanden mit Erfahrung in diesem Bereich in euer Team zu holen. Das vereinfacht die Sache beträchtlich, weil sofort und vor Ort Aussagen getroffen werden können.

Danke so weit, diese Antwort habe ich ja leider mehr oder weniger erwartet.

Wir haben bereits eine externe Firma dazugeholt, die uns ja erst auf diese Idee gebracht hat. Die Ratschläge waren aber auch sehr allgemein gehalten und man überließ uns dann, daraus die Schlüsse zu ziehen.

Vielleicht empfiehlt sich die Einrichtung einer kontrollierten Testumgebung. Dort kann man am ehesten Vergleichswerte gewinnen. Kostet halt so oder so Geld und Zeit.

CU Uwe

Danke für die Hinweis.

Wir haben uns einfach entschlossen uns die bisherigen SQL-Abfragen anzugucken, die zu Flaschenhälsen führen und dort die Optimierung für die zukünftige Neuentwicklung anzusetzen. Zusätzlich werden noch strichprobenartig einige SQL-Statements abgefeuert und die Ausführungszeiten auf ein paar Rechnern und Datenbanksystemen festgehalten.
Der Rest des DB-Designs hat sich eigentlich bewährt und wird dann so stehen bleiben.

Eine Frage habe ich aber noch…

Wir haben auch MySQL (InnoDB) mit PostgreSQL verglichen. Dabei kommt es zu etwas widersprüchlichen Ergebnissen:

  1. Rechner mit 2,6 Ghz Intel Celeron
    MySQL bei “kleiner” Ergebnismenge und weniger komplexen Abfragen deutlich schneller als PostgreSQL. Je größer und komplexer die Abfragen werden, desto mehr verschiebt sich das Kräfteverhältnis zu Gunsten von PostgreSQL, bis MySQL völlig in die Knie geht.
  2. Rechner mit 1,8 Ghz Intel Core2 4300
    PostgreSQL in jeder Hinsicht deutlich schneller.

(die Rechner sind Workstations ansonsten in der Ausstattung und Konfiguration nahezu gleich)

Kann es sein, dass PostgreSQL bei dem Core2 die Abfragen besser auf mehreren CPU-Kernen parallelisieren kann als MySQL? Oder macht PostgreSQL der geringe L2-Cache beim Celeron zu schaffen?

Die Frage kenne ich doch von irgendwoher … grübel

21:20:08 < ads> ??tweakers
21:20:09 < rtfm_please> For information about tweakers
21:20:09 < rtfm_please> see > Database test: Sun UltraSparc T1 vs. AMD Opteron (7/10) | Tweakers.net
21:20:09 < rtfm_please> or > Database test: Intel Xeon ‘Clovertown’ X5355 (7/8) | Tweakers.net

Mysql ist bei kleinen Datenmengen und einfachen Abfragen im Vorteil, weil es nicht ganz soviel Arbeit im Vorfeld erledigen muss. Einfach draus los, ohne viel zu planen, macht manchmal auch Sinn.
Sobald es aber richtig Arbeit zu erledigen gibt, möchte man diese vorgeplant haben. Schon fällt die Hauruck Methode auf die censored.

Ich kenne diesen Benchmark und ich glaube auch fast alle anderen Benchmarks mit PostgreSQL. Da aber praktisch jeder DB-Benchmark Anlass für Kritik gibt, bin ich vorsichtig, solchen Grafiken allzu viel Glauben zu schenken.

Stutzig macht mich ja eigentlich auch nur, dass PostgreSQL bereits bei weniger komplexen Abfragen MySQL aussticht oder zumindest auf Augenhöhe ist. Dabei ist gerade der Bereich der 0815-Abfragen die Domäne von MySQL.

Hmm, nein, stimmt nicht.

Der von dir angesprochene 0815-Bereich ist nur dann gut für Mysql, wenn du alle Datenbank-typischen Aktionen wie Transaktionen, Trigger, MVCC ect. aussen vor lässt … sprich, wenn du Myisam nutzt. Dann ist es schnell, richtig schnell. Aber das ist dann auch der einzige Vorteil.

Sobald du InnoDB nutzt, hast du intern die gleichen Probleme: du musst Datensätze mehrfach vorhalten, du musst Transaktionen abkapseln ect.

Schon sind alle Vorteile dahin und dann kann PostgreSQL seine bessere interne Struktur ausspielen. Natürlich wird man immer mal wieder Situationen finden, in denen eine Datenbank besser ist als die andere, generell zeigt sich aber, das der vorherige Mehraufwand, um z.B. eine komplexe Abfrage richtig vorzubereiten, sich später in besserer Performance auszahlt.

Hinzu kommt: bei vielen gleichzeitigen Anfragen greift die interne Struktur besser. PostgreSQL nutzt einzelne Prozesse, Mysql nutzt Threads. Hat beides seine Vor- und Nachteile, aber anscheinend bieten die einzelnen Prozesse eine bessere Performance … wenn man diese ausnutzen kann. Hat man z.B. viele kurze Verbindungen, die nur ein oder zwei Anfragen stellen, wird sicherlich Mysql haushoch gewinnen.