"We are back" « oc.at

PHP: geschwindigkeit Arrays vs MySQL DB

semteX 30.06.2005 - 16:31 1486 15
Posts

semteX

liebt die große KI
Avatar
Registered: Oct 2002
Location: Pre
Posts: 15042
Ich hätt ne grundlegende frage.

angenommen wir ham ne tabelle mit ein paar 1000 einträgen (id, name).

anschließend nen string wie zb.. 11/3452/984/209. Diese zahlen sind alles IDs obriger Tabelle. Was ist da schneller? Vorher die ganze tabelle in ein array verfrachten und dann über das zugreifen? Oder doch lieber jede zahl mittels sql query abfragen...

i mein klar, es hängt auch davon ab wie stark die db belastet ist,...

danke & mfg.

watchout

Legend
undead
Avatar
Registered: Nov 2000
Location: Off the grid.
Posts: 6845
Deine Fragestellung ist mehr als unklar.

Du hast eine Table und ein String - ok, das sind Datenstrukturen und die haben keine "Geschwindigkeit" wenn nichts damit gemacht wird.

Crash Override

BOfH
Registered: Jun 2005
Location: Germany
Posts: 2951
Wenn viele User das Array benutzen wirst du Probleme mit dem RAM bekommen. Es kommt halt auf die anzahl der User an.

rettich

Legend
waffle, waffle!
Avatar
Registered: Jan 2004
Location: wien
Posts: 794
Zitat von semteX
anschließend nen string wie zb.. 11/3452/984/209. Diese zahlen sind alles IDs obriger Tabelle. Was ist da schneller? Vorher die ganze tabelle in ein array verfrachten und dann über das zugreifen? Oder doch lieber jede zahl mittels sql query abfragen...

warum jede zahl? was genau willst du mit dem ergebnis machen?

mit genau einer zeilen kannst du den string "11/2134/345..." so zersplitten, dass du ein

select * from table where id in (11,2134,23...)

machen kannst. und das liefert dir in einem einzigen select statement alle passenden einträge zurück.

:confused:

Rektal

Here to stay
Registered: Dec 2002
Location: Inside
Posts: 4541
Ich hab so aehnliche Aufgaben auch schon mal gehabt. Bei mir war entscheidend dass es oft vorkam, dass die gleichen IDs (11/2134/...) bei mehreren Datensaetzen vorkamen. Da war es ohne Umschweife schneller, alles in ein Array zu lesen und dann per $array[$index] zuzugreifen. Sind die Gesamtdaten sehr gross, ist dass dann vielleicht wieder doch nicht so g'schickt. Bei paar 1000 Eintraegen hoehrt sichs net problematisch an. Mach halt Tests mit CLI-Version und schau auf den Speicherverbrauch.

semteX

liebt die große KI
Avatar
Registered: Oct 2002
Location: Pre
Posts: 15042
Zitat von rettich
warum jede zahl? was genau willst du mit dem ergebnis machen?

mit genau einer zeilen kannst du den string "11/2134/345..." so zersplitten, dass du ein

select * from table where id in (11,2134,23...)

machen kannst. und das liefert dir in einem einzigen select statement alle passenden einträge zurück.

:confused:
das wär genau das, was ich brauchn würde. kannte das "in" beim select gar ned..

Irgendwie bin i a zu blöd um auf mysql.com ne doku darüber zu finden

@all: sorry für die sehr schwammige beschreibung.

mein "problem": Das ding, das ich da grad mache (so a art "dvd backup db") liest DVDs / CDs whatever ein und speichert eben den dateinamen + den pfad jeder datei in die mysql db.

sinn dahinter ist folgender: ich such z.B.: irgend a spezielles backups von den datein => weboberfläche => suchen => i weiß sofort auf welcher DVD die betreffende Datei drauf ist.

Natürlich sind meist mehr Datein in nem Ordner als nur 1 => er speichert (hausnummer 100x) /eigene dateien/blahr/muh als pfad. verbraucht halt viel platz.
meine idee ist jetzt folgende: ich schau ob ich schon irgendwo in meiner "ordnertabelle" "eigene dateien" hab. wenn ned wird der eintrag angelegt und ma hat dann natürlich auch ne id. schaut dann so aus:

Ordnertabelle

--ID--|--Ordner--|
23-----eigene dateien
24-----blahr
25-----muh

Ich müsste also bei jeder datei nur noch 23/24/25 als "ordner" speichern.

So ich hoff das hört sich jetzt ned ganz wirr an. ists überhaupt sinnvoll, was ich da mache?

nachtrag: so wieder die hälfte vergessen:

die konkrete frage ist eben: wenn ich mir jetzt (hausnummer) 1000 files anzeigen lasse, ist es dann besser wenn ich 1x die ganze Ordnertabelle in ein array umspeichere & dann mithilfe dieses Arrays den "originalnamen" wiederherstelle oder fährt man besser wenn man einfach 1000x die mysql db abfragt (bei 1000 files...).

Mir ist natürlich klar, dass in diesem Beispiel die Geschwindigkeit sowieso realtiv duttl ist (1 Anwender, relativ unbelasteter Server).

Danke & mfg.

@Rektal: jop werd i eh a no machn :)
Bearbeitet von semteX am 30.06.2005, 18:34

gue

Addicted
Avatar
Registered: Feb 2003
Location: Linz
Posts: 400
Also ich würds vielleicht so machen:
Du hast 2 Tabellen, eine speichert die Verzeichnisse, eine die Dateien, beispielsweise:

Verzeichnisse := _id_, path
Dateien := _id_, dir_id, name

Inhalte beispielsweise:
Code:
Verzeichnisse:
id | path
---+-----
1  | eigene dateien/hans
2  | eigene dateien/hans/wurst
3  | eigene dateien/hans/marmelade
...

Dateien:
id | dir_id | name
---+--------+-----
1  | 1      | lala.jpg
2  | 1      | bubu.jpg
3  | 2      | lala.jpg
...

Wenn du das dann abfragst, kannst du das ganze über einen Join verbinden. Bekommst zwar dadurch ein großes Resultset aber ich _rate_ jetzt mal, dass das schneller ist, als das ganze in ein Array zu stopfen und dann zu verbinden.

semteX

liebt die große KI
Avatar
Registered: Oct 2002
Location: Pre
Posts: 15042
diese möglichkeit ist sicher schneller, aber wiederum nicht das optimum an "platzersparniss".

in deinem beispiel würde 3x "eigene dateien", 3x "hans" in der tabelle stehen (eben für jeden unterordner alles 1x..)

bei mir wärs nur 1x eigene dateien, 1x hans, 1x wurst, 1x marmelade

watchout

Legend
undead
Avatar
Registered: Nov 2000
Location: Off the grid.
Posts: 6845
IN() -> http://dev.mysql.com/doc/mysql/en/c...-operators.html

"Optimum" an Platzersparnis wär aber ein "Objektorientierter" Ansatz... (beware tha quotation)

Code:
dirs  ([u]dirID[/u], parentID, name)
files ([u]dirID, name[/u])

that

Hoffnungsloser Optimist
Avatar
Registered: Mar 2000
Location: MeidLing
Posts: 11363
Zitat von semteX
diese möglichkeit ist sicher schneller, aber wiederum nicht das optimum an "platzersparniss".

Ist das bei deinen Datenmengen in dieser Anwendung wirklich das Ziel, auf das du hinoptimieren solltest?

semteX

liebt die große KI
Avatar
Registered: Oct 2002
Location: Pre
Posts: 15042
Zitat von that
Ist das bei deinen Datenmengen in dieser Anwendung wirklich das Ziel, auf das du hinoptimieren solltest?
Hab gestern noch ein bissi herumgespielt => 50k "file einträge" brauchn in der DB ca 2 MB... antwort: nein. Das ganze ist eh eher a bissi zum "lernen" gedacht.

rettich

Legend
waffle, waffle!
Avatar
Registered: Jan 2004
Location: wien
Posts: 794
wie wärs mit einer intersection table?

speichere filme und speicherorte extra. für jeden film und für jeden möglichen speicherort jeweils einen eintrag. in der intersection table hängst du die zwei zusammen - also film1 zu ort1, film2 zu ort2, film3 zu ort1, film4 zu ort3 usw

so kannst du, wenn du einen film anlegst, prüfen, obs den speicherort schon gibt. wenn ja, einfach ID vom speicherort holen und gemeinsam mit der film-ID in die intersection table schreiben. wenns den speicherort noch nicht gibt, legst den zuerst neu an und nimmst dann erst die ID und schreibst die mit der film-ID in die DB.

so hast jeden speicherort und jeden film nur einmal in der DB abgelegt und sparst platz. die abfrage über "wo liegt welcher film" kriegst über ein statement mit zwei joins (film join intersection join speicherort) zurück.

watchout

Legend
undead
Avatar
Registered: Nov 2000
Location: Off the grid.
Posts: 6845
Zitat von rettich
wie wärs mit einer intersection table?

speichere filme und speicherorte extra. für jeden film und für jeden möglichen speicherort jeweils einen eintrag. in der intersection table hängst du die zwei zusammen - also film1 zu ort1, film2 zu ort2, film3 zu ort1, film4 zu ort3 usw

so kannst du, wenn du einen film anlegst, prüfen, obs den speicherort schon gibt. wenn ja, einfach ID vom speicherort holen und gemeinsam mit der film-ID in die intersection table schreiben. wenns den speicherort noch nicht gibt, legst den zuerst neu an und nimmst dann erst die ID und schreibst die mit der film-ID in die DB.

so hast jeden speicherort und jeden film nur einmal in der DB abgelegt und sparst platz. die abfrage über "wo liegt welcher film" kriegst über ein statement mit zwei joins (film join intersection join speicherort) zurück.
sorry hab ich da grad was besonderes überlesen oder ist das wirklich nur eine n:m beziehung in Worten erklärt?

Das ist aber eigentlich eine 1:n Beziehung, deswegen braucht man keine Intersection Table und spart noch mehr Platz :eek:

rettich

Legend
waffle, waffle!
Avatar
Registered: Jan 2004
Location: wien
Posts: 794
Zitat von watchout
sorry hab ich da grad was besonderes überlesen oder ist das wirklich nur eine n:m beziehung in Worten erklärt?

nein. genau das wars. aber nach dem er net amal ein "where x in" kennt, hab ichs mal ausführlich erklärt ;)

Zitat
Das ist aber eigentlich eine 1:n Beziehung, deswegen braucht man keine Intersection Table und spart noch mehr Platz :eek:

so wie ich das verstanden hab, will ers ja auflösen, weils KEINE 1:n beziehung ist (ein speicherort könnte ja öfter verwendet werden). wenn er nur die filenamen direkt speichert, ist es natürlich eine 1:n und dann hast du vollkommen recht.

watchout

Legend
undead
Avatar
Registered: Nov 2000
Location: Off the grid.
Posts: 6845
paths (pathID, path)
files (pathID, filename)
hier ist kein pfad doppelt... oder irre ich mich?

das is aber alles egal, weil imho ist die Platzersparnis in keiner relation zum Performanceunterschied allein der join der notwendig ist, macht alles zunichte - deswegen ist die einzige Möglichkeit, die Sinn macht:
files (path_filename)
auch wenn statt 3MB vielleicht 4MB verbraucht werden...
Kontakt | Unser Forum | Über overclockers.at | Impressum | Datenschutz