# Was ist Performance-Mäßig besser?



## professorchimp (7. Dez 2009)

Hallo,

folgendes szenario:
Ich schreibe ein Web-Communityskript und benutzte eine MySql-Datenbank.
In der DB gibt es eine Tabelle "Mitglieder". Dort sind für alle mitglieder neben benutzername und passwort noch eine Menge anderer Daten gespeichert, von Namen und Adresse über Hobbys bis Lieblingsmusik. Insgesamt ca. 50 felder.
Wäre es sinnvoll diese Tabelle in mehrere Tabellen aufzuspalten? 

Wenn ich jetzt auf einer Seite einen Aufruf "Select Benutzer_ID From Mitglieder where...." mache, läd dann mein DBS erstmal die ganze riesen Mitgliedertabelle und pickt dann raus was gebraucht wird? In dem Fall wäre es ja aufjedenfall besser die tabelle zu splitten.

Hatte zwar mal ne DBS vorlesung, weiß da aber leider nicht mehr so genau bescheid und bevor ich was unglaublich ressourcenfressendes programmiere frag ich lieber mal nach ;-)


Danke für eure Hilfe
P.C.

PS: Ich meine mit Splitten nicht, dass ich die ersten x rows in eine tabelle packe und die nächsten in ne andere, sondern splitten indem ich z.B. in einer Tabelle nur username und passwort speichere, in eine andere namen und adressen, in eine andere hobbies und interessen, etc. obwohl das von den Normalformen her eigentlich nicht nötig wäre.


----------



## Empire Phoenix (7. Dez 2009)

Keine Sorge, die DBServer jegliche mir bekannten Datenbank sollten intelligent genug sein das selber effizient zu managen (das ist ja einer der Hauptgründe die zu benutzen), zumindest war bei privaten Anwendung gleich welcher Art der DB server bislang immer das kleinste Problem


----------



## Gast2 (7. Dez 2009)

professorchimp hat gesagt.:


> Hatte zwar mal ne DBS vorlesung, weiß da aber leider nicht mehr so genau bescheid und bevor ich was unglaublich ressourcenfressendes programmiere frag ich lieber mal nach ;-)


dann wird es Zeit das Du das nachholst  - Normalisierung (Datenbank) ? Wikipedia - wenn Du das durch hast, dann kannst Du Dir Deine Fragen selbst beantworten

hand, mogel


----------



## MrWhite (7. Dez 2009)

Ich möchte zu dieser Fragestellung gerne auf folgenden Link verweisen: When and why are database joins expensive? - Stack Overflow

Besser und prägnanter habe ich es bisher noch nirgends gelesen. Mit bestem Dank an David Aldridge.



> Denormalising to improve performance? It sounds convincing, but it doesn't hold water.
> 
> Chris Date, which advanced the relational data model along with Dr Ted Codd, its creator, got tired of misinformed arguments against normalisation and systematically demolished them using scientific method - he got large databases and tested these assertions. I think he wrote it up in Relational Database Writings 1988-1991 but this book was later rolled into edition six of Introduction to Database Systems. This is the definitive text on database theory and design, currently in its eighth edition. Chris Date was an expert in this field when most of us were still running around barefoot.
> 
> ...


----------



## ice-breaker (7. Dez 2009)

Als Randbemerkung noch: Es gibt in Datenbanken noch weit mehr Performanzindikatoren als Joins: Views, Subselects, Gruppen-Operationen (GROUP BY), schlechte Indizes, zu große Tabellen, MyIsam, Trigger viele Punkte können eine schlechte Performance bewirken, aus dem Grunde ist es das Beste, die Datenbank sinnvoll über ORM zu kapseln, denn den einen oder anderen Fehler wirst du sicherlich machen, es ist nur eben die Frage, wie leicht man diese nachher wieder beheben kann 

Und ja soviele Attribute in einer MySQL-Tabelle sind wirklich negativ  Denn das Caching von MySQL (InnoDB) setzt du damit unter eine Bewährungsprobe, die Caches sind per Default relativ klein eingestellt, wenn nun jeweils einen so großer Datensatz darin gespeichert wird, müssen andere Daten wieder rausgeräumt werden, es finden viele Cache-Misses statt.

Wer sich für das Thema (im speziellen MySQL) wirklich interessiert, dem kann ich die 1. und 2. Auflage des High Performance MySQL Buches aus dem O'Reilly-Verlag nahe legen. Es wird wirklich ein sehr großer Teil abgedeckt was man wissen kann, natürlich nicht alles, aber speziell in der 2. Auflage wird darauf eingegangen wie eine DB funktioniert, was essentiell ist, um Optimierungen durchführen zu können.


----------



## Gast2 (7. Dez 2009)

ich finde die Dokumentation von MySQL zum Thema Optimierung schon recht ausführlich


----------



## professorchimp (7. Dez 2009)

@mogel: Über die normalformen weiß ich schon bescheid. Hilft mir bei meinem Problem aber nicht weiter, denn meine Riesentabelle ist ja in BCNF.



> Und ja soviele Attribute in einer MySQL-Tabelle sind wirklich negativ Denn das Caching von MySQL (InnoDB) setzt du damit unter eine Bewährungsprobe, die Caches sind per Default relativ klein eingestellt, wenn nun jeweils einen so großer Datensatz darin gespeichert wird, müssen andere Daten wieder rausgeräumt werden, es finden viele Cache-Misses statt.


Heißt das jetzt du würdest die tabelle vertikal splitten?


----------



## Meldanor (7. Dez 2009)

Nun ja, du hast ja gesagt, du speichert Informationen über die Mitglieder.
Eventuel doppeln sie sich und du kannst Tabelleninformationen zusammenführen.
Hobbys zum Beispiel in eine andere Tabelle auslagern und statt dem String selber in der Tabelle nur ein int als Verweis auf die andere Tabelle machen. So kürzt du das auch schon.
Wenn du jedoch die Tabelle auf keinen Fall noch weiter aufspalten kannst, dann hat diese Entinität 50 Attribut und diese in 2 Hälften aufspalten, ist wenig sinnvoll, da du dann abwechselnd über beide schreiben müsstest(wenn Tabelle 1 Max ungerade, dann schreibe in Tabelle 2?). Dort müsstest du durch die Spaltung sehr auf Datenkonsistenz achten, weil die kann dann schnell flöten gehen und diesen Aufwand zu relativieren mit dem höheren Leistungsverbraucht ~ würde ich sage, dass lohnt sich nicht, vorallem, weil auch die Übersicht leidet.


----------



## ice-breaker (7. Dez 2009)

professorchimp hat gesagt.:


> Heißt das jetzt du würdest die tabelle vertikal splitten?


ja, 50 sind sowieso zuviel, da behält doch keiner den Überblick.
Ich würde das aufteilen in Attribute, die oft genutzt werden (damit diese regelmäßig im cache sind), und attribute die seltener genutzt werden, und diese wahrscheinlich noch sinnvoll aufteilen.

Aber ich denke mal die Normalformen werden dir die 50-spaltige Tabelle sowieso aufsplitten.


----------



## Gast2 (8. Dez 2009)

professorchimp hat gesagt.:


> Hilft mir bei meinem Problem aber nicht weiter, denn meine Riesentabelle ist ja in BCNF.



nein ist sie nicht ... Deine Datenbank hat noch nicht mal die 1. Normalform erreicht ... oder haben Deine Mitgliieder nur ein Hobby? ... wie trennst Du die Hobbys untereinander in der Spalte? ... öhm - Lieblingsmusik? ... %WASAUCHIMMER



			
				Wikipedia - 1. Normalform hat gesagt.:
			
		

> Jedes Attribut der Relation muss einen atomaren Wertebereich haben und frei von Wiederholungsgruppen sein


Normalisierung (Datenbank) ? Wikipedia


----------



## professorchimp (9. Dez 2009)

mogel hat gesagt.:


> nein ist sie nicht ... Deine Datenbank hat noch nicht mal die 1. Normalform erreicht ... oder haben Deine Mitgliieder nur ein Hobby? ... wie trennst Du die Hobbys untereinander in der Spalte? ... öhm - Lieblingsmusik? ... %WASAUCHIMMER
> 
> 
> Normalisierung (Datenbank) ? Wikipedia



Die Mitglieder können bei diesen Feldern einen Fließtext eingeben, da soll nicht nach einzelnen Hobbys getrennt werden. Zwei Einträge von zwei verschiedenen mitgliedern könnten zum Beispiel sein:
(1) "Basketball, Fußball, Flugzeugträger besichtigen"
(2) "Ich lese gerne Bücher von Astrid Lindgren"


----------



## Empire Phoenix (9. Dez 2009)

Das ist allerdings nicht der Sinn von relationalen Datenbanken


----------



## fastjack (9. Dez 2009)

Mach doch einfach mal ein paar Performancetests. Fülle die Tabelle mit tausenden von Zufallszeilen und teste dann select, insert und update. Wie viele Mitglieder sind überhaupt zu erwarten ? Es gibt schon Unterschiede ob es nur Hundert oder eine Million sind.

Ansonsten würde ich auch zur Normalisierung raten, aber es kommt sicherlich auf den konkreten Anwendungsfall an. Eine Historientabelle, bestehend aus millionen von Datenzeilen würde ich im ganzen Leben nie wieder normalisieren. Bei Stammdatentabellen, die immer wieder gewartet werden, würde ich immer Normalisieren.

Wie willst Du z.B. nach Hobbies gruppieren oder sortieren ?


----------



## ice-breaker (9. Dez 2009)

Empire Phoenix hat gesagt.:


> Das ist allerdings nicht der Sinn von relationalen Datenbanken



ist aber leider das, was Nutzer von Sozialen Netzwerken (Web-Communitys) erwarten, Facebook und StudiVZ haben es vorgemacht, dann erwarten sie es von allen anderen auch so.

Sollte das Fließtext sein, müssen diese Attribute *unbedingt* in eine andere Tabelle, denn Text-Spalten wirken sich nicht sehr positiv auf die Performance aus.
Ein Blick auf die Kompression des InnoDB Plugins kann da auch wieder einen gewaltigen Performanceschub bringen


----------



## Gast2 (9. Dez 2009)

ice-breaker hat gesagt.:


> ist aber leider das, was Nutzer von Sozialen Netzwerken (Web-Communitys) erwarten, Facebook und StudiVZ haben es vorgemacht, dann erwarten sie es von allen anderen auch so.


Datenhaltung und Datendarstellung sind zwei Geschichten ... MVC


----------



## ice-breaker (9. Dez 2009)

mogel hat gesagt.:


> Datenhaltung und Datendarstellung sind zwei Geschichten ... MVC


richtig, nun sag mir aber wie du fließtext, in der jemand seine Hobbys beschreibt (Auflistung vs. Roman), sinnvoll in einer relationalen Datenbank speichern willst, das geht eben nicht.

Auf Deutsch: In der Darstellung wird Fließtext von den Nutzern gefordert, aus diesem Grunde hast du aber bei der Datenhaltung eine Abhängigkeit von der Dateneingabe.


----------



## Gast2 (9. Dez 2009)

Trennung anhand der Komma ... evt. noch Leerzeichen (kann aber nach hinten los gehen)


----------



## ice-breaker (9. Dez 2009)

Hobbys von Mogel:

Typ1: "Rad fahren, Fitnessstudio"

Typ2: "Früher bin ich viel Rad gefahren, aber seit dem der Wanderweg im Wald gesperrt wurde, fahre ich kaum noch, aber dafür habe ich ja ein Fitness-Studio um die Ecke, welches von mir regelmäßig besucht wird"

Für Typ1 mag das trennen noch gehen, aber da wir eine Textbox anbieten, die keine Regeln für die Eingabe macht, können wir nicht implizieren, dass alles nach Typ1 eingegeben wird, also bleibt uns nur die Möglichkeit es auch als Fließtext zu speichern, da auch Personen Typ2 eingeben können, das meine ich damit.

Teilweise ist die Datenhaltung von der Datendarstellung abhängig und Konzepte der relationalen Datenbanken müssen aufgebrochen werden.


----------



## Gast2 (9. Dez 2009)

Du kannst das aber über eine zweite Tabelle und einen FK "verstecken"


----------



## robertpic71 (9. Dez 2009)

Als erstes: Selbst "schwache" Datenbanken sollten solche Fehldesigns locker wegstecken. Ich gehe einmal davon aus, dass du die 10.000 Marke nicht wesentlich übersteigst. Bei diversen "Legacy-Anwendungen" müssen die Datenbank viel mehr aushalten... 

Die Größe der Resultsets hängt ja nicht nur von der Tabelle ab, sondern auch davon, wieviel Felder man im Select angibt.
Ein Select Id, Name, password from mitglieder liefert nur diese 3 Felder zurück. 

Wie schon von Anderen angesprochen, da gibt es Faktoren, welche dich (mit wenig DB Wissen) eher ausbremsen.

- wenn immer Möglich: die Selektion mit dem SQL where abdecken
- für die Zugriff einen Index anbieten, also z.B. Nach Mitgielder Index nach Name für die Passwortprüfung (damit scannt er nicht die ganze Datei durch)

und 1000+1 "kleine Tipps" als PreparedStatement verwenden usw.

Zur Anforderung der Hobbies:
Es wird immer wieder Anforderungen nach "unstrukturierten" Daten geben. Das ist solange kein Problem, bis man die Daten irgendwie filtern, prüfen oder sonst irgendwie auswerten will.

Bei kleinen Datenmengen wird es keine Rolle spielen, aber ich vermeide Fließtextfelder in der Hauptdatei.


/Robert


----------



## tom198 (10. Dez 2009)

mogel hat gesagt.:


> Du kannst das aber über eine zweite Tabelle und einen FK "verstecken"


Aber genau das steht doch bereits in #14 :autsch:


----------



## mabus (10. Dez 2009)

professorchimp hat gesagt.:


> Hallo,
> 
> folgendes szenario:
> Ich schreibe ein Web-Communityskript und benutzte eine MySql-Datenbank.
> ...



Hm..ich würde mir in deinem Falle erstmal Gedanken um die Use-Cases machen. Der Name einer Person (eines Mitgliedes) wird vermutlich wesentlich häufiger abgerufen werden (z.b. Suche, Freundesliste, etc) als seine Interessen, Hobbies und dergleichen (Profilseite)...

Ergo macht es durchaus schon Sinn, die Daten ein wenig danach zu trennen, zu welchen Zwecken sie benötigt werden (also als Beispiel Stammdaten und personenbezogene Detaildaten).


----------

