"Christmas - the time to fix the computers of your loved ones" « Lord Wyrm

Mysql Speed

Maehmann 20.02.2003 - 22:13 4811 44
Posts

Maehmann

OC Addicted
Avatar
Registered: Aug 2002
Location: Vienna
Posts: 1110
Hey Leute

Wenn ich bei meiner aktuellen Site eine Datenbankabfrage mache, die mehrere ca. 300 Datensätze mit 11 Zellen/Datensatz zurückgibt, dauert diese Abfrage schon recht lange. Man hat einer merkliche Verzögerung von ca. 1 Sekunden, bis die Seite komplett angezeigt wird. (Ausgegeben wird das Ganze dann in einer While Schleife in Form einer Tabelle)

1te Frage: Ist das normal? Oder ist die Datenbank meines Hosters einfach lahm? :bash:

2te Frage: Würde es speedmäßig etwas bringen, wenn ich das erhaltene Array z.B. in einer Session speichere und anschließend alles weitere mit diesem array mache (nachträgliches sortieren, darin suchen, usw.)?
Das dumme an der Lösung wäre halt, dass ich das array neuladen muss, sobald etwas an den Datensätzen geändert wurde.

*tia*

Christoph

@Mods: THX for moving :)
Bearbeitet von Maehmann am 20.02.2003, 22:19

atrox

in fairy dust... I trust!
Avatar
Registered: Sep 2002
Location: HTTP/1.1 404
Posts: 2782
zeig her deine query, zeig her dein tabellen-modell.

300 records downloaden kann natürlich etwas zeit dauern, aber vielleicht verbraucht die abfrage (zb aufgrund fehlender indeces, cpu-fressenden bedingungen) unnötig lange.

Maehmann

OC Addicted
Avatar
Registered: Aug 2002
Location: Vienna
Posts: 1110
Query ist: mysql_query ("SELECT * FROM filme ORDER BY $sortby ASC");

Hmmm ... indices ... hmmm ...

Die Tabelle schaut so aus ...

click to enlarge

Hoffe das reicht so ... Die Typen der Zellen müssen noch angepasst werden.

atrox

in fairy dust... I trust!
Avatar
Registered: Sep 2002
Location: HTTP/1.1 404
Posts: 2782
die mysql-text-shell gibt dir zur jeder query eine bearbeitungszeit aus. mach einen test, dann lege für die meisten suchkriterien einen index an, und teste nochmal.

PS: gibst du immer alle 300 auf einmal aus? falls nicht, schau dir die LIMITS-klausel an.

Maehmann

OC Addicted
Avatar
Registered: Aug 2002
Location: Vienna
Posts: 1110
Also es gibt eine Seite, wo er alle auf einmal ausgibt
Hmmm ... Vielleicht mach ich einfach mehrere Seiten draus und lass pro Seite nur 50 oder 100 ausgeben.
Ansonsten gibt er nur bestimmte Datensätze aus, z.B. alle die seit dem letzten Login neu sind.

Das dumme ist ja, dass bei einer SELECT * Abfrage die Indices nichts helfen. Oder irre ich da?

atrox

in fairy dust... I trust!
Avatar
Registered: Sep 2002
Location: HTTP/1.1 404
Posts: 2782
beim sortieren sollten sie helfen, oder irre ich mich ?

ausserdem gilt auch zu bedenken, daß der aufbau von tabellen mit sehr vielen zeilen oder spalten auch beim browser zeit kostet.

Maehmann

OC Addicted
Avatar
Registered: Aug 2002
Location: Vienna
Posts: 1110
okidoki.
Werd mir das morgen mal genauer anschauen und durchtesten.

watchout

Legend
undead
Avatar
Registered: Nov 2000
Location: Off the grid.
Posts: 6845
du hast da ein paar sachen in die datenbank eingebaut:
1. du speicherst 300 mal zb. das genre hinein, da sich das aber immer wiederholt wäre es intelligenter, nur einen integer-index in das feld zu schreiben und diesen dann später zuordnen (das gleiche mit sprache, quali - besitzer unter umständen und codec)

2. du hast mehrere felder die nicht null sein dürfen, aber keinen default-wert haben

3. der einzige schlüssel den du hast is ein integer, statt eines bigint und wahrscheinlich noch signed

4. das datum is ein bigint... ähm, wofür gibt es das date, datetime, timestamp-formate?

wenn du zumindest punkt 1 "behebst" wird deine datenbank um ca 1/3 kleiner... und die memorynutzung sinkt auch gewaltig -> mehr speed ;)

Maehmann

OC Addicted
Avatar
Registered: Aug 2002
Location: Vienna
Posts: 1110
Zitat von watchout
du hast da ein paar sachen in die datenbank eingebaut:
1. du speicherst 300 mal zb. das genre hinein, da sich das aber immer wiederholt wäre es intelligenter, nur einen integer-index in das feld zu schreiben und diesen dann später zuordnen (das gleiche mit sprache, quali - besitzer unter umständen und codec)

2. du hast mehrere felder die nicht null sein dürfen, aber keinen default-wert haben

3. der einzige schlüssel den du hast is ein integer, statt eines bigint und wahrscheinlich noch signed

4. das datum is ein bigint... ähm, wofür gibt es das date, datetime, timestamp-formate?

wenn du zumindest punkt 1 "behebst" wird deine datenbank um ca 1/3 kleiner... und die memorynutzung sinkt auch gewaltig -> mehr speed ;)

Thx für die Tips ... werd das mal umsetzen ...
datum ist absichtlich ein bigint da ich dort den phptimestamp speichere und nicht den von mysql.

@Signed: Wo genau liegt der Unterschied zwischen signed und unsigned?

PS: Ist übrigens mein erster wirklicher Versuch etwas mit mysql zu programmieren ;)

Guest

Deleted User
Registered: n/a
Location:
Posts: n/a
Zitat von watchout
du hast da ein paar sachen in die datenbank eingebaut:
1. du speicherst 300 mal zb. das genre hinein, da sich das aber immer wiederholt wäre es intelligenter, nur einen integer-index in das feld zu schreiben und diesen dann später zuordnen (das gleiche mit sprache, quali - besitzer unter umständen und codec)

was ist schneller: ein "select *" wo das genre als varchar drin steht oder ein integer-wert mit einem "join" auf die genre-tabelle :confused:

ich nehme, es ist nicht der join. die vom db-server übertragene datenmenge bleibt aber gleich.

(wobei ich natürlich zustimme: mit einer genre-table ist das db modell sauberer, egal, wie viel zeit das kostet :))

Maehmann

OC Addicted
Avatar
Registered: Aug 2002
Location: Vienna
Posts: 1110
Sodala hab jetzt mal die indices getestet.
Leider ohne Erfolg

Ein Query nach SELECT * FROM filme ORDER BY genre, titel ASC dauert 0,42secs

egal ob ich einen index genre,titel hab oder nicht.
Vorausgesetzt ich hab beim adden des Index nichts falsche gemacht.
Verwendet hab ich folgeneden Query: ALTER TABLE `filme` ADD INDEX (genre,titel)

Maehmann

OC Addicted
Avatar
Registered: Aug 2002
Location: Vienna
Posts: 1110
Zitat von rettich
was ist schneller: ein "select *" wo das genre als varchar drin steht oder ein integer-wert mit einem "join" auf die genre-tabelle :confused:

ich nehme, es ist nicht der join. die vom db-server übertragene datenmenge bleibt aber gleich.

(wobei ich natürlich zustimme: mit einer genre-table ist das db modell sauberer, egal, wie viel zeit das kostet :))

Das ist eine gute Frage ;)
Vorallem würde das bei mir dann auf mehrere "Joins" hinauslaufen. genre, besitzer, codec_vid, codec_aud usw.

Jetzt stell sich die Frage ob das wirklich sinnvoll ist, da ich die ganze Sache dann umprogrammieren müsste und noch dazu die bereits bestehenden Tabellen ändern müsste.
Die Queries selbst würden dann auch immer länger und unübersichtlicher werden.

Und wie siehts mit INSERT und UPDATE aus? kann ich da auch joins verwenden? Hab dazu nix brauchbares finden können :(
Bearbeitet von Maehmann am 21.02.2003, 11:51

Guest

Deleted User
Registered: n/a
Location:
Posts: n/a
Zitat von Maehmann
Jetzt stell sich die Frage ob das wirklich sinnvoll ist,

sinnvoll ist es ohne zweifel; wenn man es von anfang an macht und durchzieht.

atrox

in fairy dust... I trust!
Avatar
Registered: Sep 2002
Location: HTTP/1.1 404
Posts: 2782
wir wollen ihn nicht gleich beim ersten programm mit er-modellen und 3. Normalform (3NF) zuschütten, mittelfristig sollte maehmann sich das aber unbedingt anschauen.
wer ein gutes leicht verständliches tutorial dazu hat, möge es hier posten.
dieses ist zwar für access, erklärt den aufbau aber mit recht einfachen worten: http://www.uni-koeln.de/rrzk/kurse/...n/access/er.pdf
PS: das sortieren nach zwei varchar(200) feldern ist natürlich wirklich sehr cpu lastig ;(

ob die lösung mit detail- bzw lookup-tables wirklich langsamer ist, müssate man ausprobieren: zwar ist das joinen zweier tabellen komplexer, dafür muß in der zweiten tabelle eine kleinere datenmenge sortiert werden, und dann können bereits die IDs auf die haupttabelle angewand werden, und man muß nur noch die elemente sortieren, welche die selbe detail-id besitzen. die besten sortier-algorithmen haben etwa einen aufwand von n*log(n). kann man diese sortierte menge in zwei einzeln zu sortierende menge teilen, dann reduziert sich der gesamt-aufwand; 2*(n/2*log(n/2)) ist weniger als n*log(n). das verhältnis wird umso besser, je mehr genres es gibt.
ausserdem ist der stringvergleich vieler identer strings langsamer als der vergleich unterschiedlicher strings. das liegt daran, daß identität erst beim vergleich des letzen zeichens festgestellt wird, während größer/kleiner mit dem ersten nicht identen zeichen feststeht.welcher effekt (komplexität gegen optimierung) bei 300 datensätzen stärker ins gewicht fällt, traue ich mir hier nicht zu sagen.

Maehmann

OC Addicted
Avatar
Registered: Aug 2002
Location: Vienna
Posts: 1110
Ich kenn das tutorial http://ffm.junetz.de/members/reeg/DSP/

Ist glaub ich auch ganz brauchbar. Wär mir das Kapitel mit den Normalformen gleich mal genau anschauen ;)
Kontakt | Unser Forum | Über overclockers.at | Impressum | Datenschutz