Sortering/prioritering/sammenkædning af store datamængder

Her postes alt, som ikke direkte har noget med Ubuntu at gøre.
js79
Indlæg: 124
Tilmeldt: 24. sep 2008, 19:47
Geografisk sted: Holstebro

Sortering/prioritering/sammenkædning af store datamængder

Indlæg af js79 »

Hej folkens

Svært at finde en passende titel på dette indlæg.

Jeg har en programmeringsopgave, hvor jeg godt kunne bruge lidt feedback. Ved ikke hvor meget hjælp der er at hente på dette forum, men måske nogen kender nogen eller noget der kan hjælpe alligevel.

Setup'et er PHP/MySQL og problemet er hastighed, hastighed og atter hastighed. Jeg har omkring 25000 produkter, som er kædet sammen med 200 forskellige egenskaber/oplysninger. Den endelige løsning, skal gerne resultere i, at man skal kunne søge på hver enkelt egenskab og når dette er gjort, skal man få vist de varer der matcher søgningen. Herefter skal man kunne hakke en egenskab mere af og søgningen skal igen opdatere. Det lyder simpelt, men jeg ved simpelthen ikke hvordan jeg bygger min søgning op, så det bliver hurtig nok. Hastigheden er en meget vigtig faktor og der bruges bla. Ajax til præsentationen, for at minimere outputtet til browseren.

Databasestrukturen er i øjeblikket én tabel, med 25000 rækker og 200 kolonner, hvor der er index'es på de felter der bliver brugt til søgninger i dag. Jeg ved ikke, om databaseopbygningen bør ændres, men jeg ved at opslagene allerede i dag kører for langsomt, så jeg tror ikke yderligere indexes er vejen frem, ligesom "ORDER BY" også i dag er for langsom og er skiftet ud med array-sortering i PHP, som performer langt bedre.

Det var den korte version :)

Nogle gode idéer til, hvordan jeg kommer videre? Nogle specielle sorteringsteknikker man bør kende?

JS
Jarlen
Indlæg: 834
Tilmeldt: 1. jun 2008, 18:23
IRC nickname: Jarlen
Geografisk sted: København

Re: Sortering/prioritering/sammenkædning af store datamængder

Indlæg af Jarlen »

js79 skrev:Databasestrukturen er i øjeblikket én tabel, med 25000 rækker og 200 kolonner


Jeg tror jeg har fundet din flaskehals :P

Jeg forstår ikke helt hvad det er for nogle egenskaber du vil søge efter osv, kan du prøve at give et lille eksempel, så kan det være jeg har et forslag til hvordan du kan normalisere din database (jeg antager du kender til normalisering).
jesperjarlskov.dk - Blog om Ubuntu, fri software og andet godt :-)
js79
Indlæg: 124
Tilmeldt: 24. sep 2008, 19:47
Geografisk sted: Holstebro

Re: Sortering/prioritering/sammenkædning af store datamængder

Indlæg af js79 »

Jarlen skrev:
js79 skrev:Databasestrukturen er i øjeblikket én tabel, med 25000 rækker og 200 kolonner


Jeg tror jeg har fundet din flaskehals :P

Jeg forstår ikke helt hvad det er for nogle egenskaber du vil søge efter osv, kan du prøve at give et lille eksempel, så kan det være jeg har et forslag til hvordan du kan normalisere din database (jeg antager du kender til normalisering).


Mit setup er lidt komplekst, så det er svært at beskrive helt uden at skulle skrive rigtig rigtig meget og det orker jeg ikke helt :) Dette problem er en lille del af en større søgemekanisme. Men altså. Lad os sige, at jeg har 25.000 computere (bare som eksempel) og 200 forskellige komponenter. Min tabel indeholder så 25.000 rækker og 200 kolonner.

----------------------
| navn | 1 gb kingston | 2 gb kingston | ...............
| computer 1 | ja | nej | .................
| computer 2 | nej | ja | .................
...
----------------------

Jeg skal gerne frem til et system, hvor man får vist x-antal felter i en søgefunktion med komponenter hvor der ud for hvert komponent er oplyst hvor mange produkter komponentet findes i og så snart man vinger et nyt komponent af, skal antallet udfor de resterende komponenter opdateres, således at man kan følger med i hvor mange man nu har udelukket.

Giver det mening?

Jeg ved godt, at jeg i teorien burde have en tabel med komponenterne, en tabel med produkter og en tabel der kæder de 2 ting sammen, men ved de test jeg har lavet performer det bare SÅ ringe at det slet ikke er løsningen.

Hertil skal jeg måske også nævne, at der skal være mulighed for at lave en sortering på baggrund af hver komponent. Her har jeg testet ORDER BY i forhold til diverse sort()-funktioner i php og her performer sidstnævnte altså bedst.
Jarlen
Indlæg: 834
Tilmeldt: 1. jun 2008, 18:23
IRC nickname: Jarlen
Geografisk sted: København

Re: Sortering/prioritering/sammenkædning af store datamængder

Indlæg af Jarlen »

Jeg tror nu stadig jeg ville smide det ud i flere tabeller. Du skal huske at sætte dine foreign keys på disse forbindelse før det virker. Evt noget á la:

maskintabel
|id|navn | antalRam | RamType |
| 1|Computer1 | 2 | 1 |
| 2|Computer2 | 1 | 3 |

ramtabel
|id|ramNavn|
|1|Kingston|
|2|Unnamed|
|3|etAndetNavn|

Så laver du en foreign key der siger at maskintabel.RamType kun må indeholde muligheder der findes i ramtabel.id
Dette vil give flere fordele, bl.a. slipper du for at gentage navnet på dine ram hele tiden, men det er jo rent pynt.
Den virkelige fordel vil være at det er lettere at finde og sortere maskinerne efter antallet af ram, da der nu er tale om et integer, i stedet for en string. Det er jo på alle måder lettere at sortere:
3, 3, 1
end
3 Kingston, 3 unnamed, 1 kingston
Desuden kan du let og hurtigt udtrække de maskiner der bruger en bestemt ramproducent/type, da du har en foreign key, så når du finder typen i din ramtabel, er det bare at trække alle de computere hvor computer.ramType = ramtabel.id
jesperjarlskov.dk - Blog om Ubuntu, fri software og andet godt :-)
js79
Indlæg: 124
Tilmeldt: 24. sep 2008, 19:47
Geografisk sted: Holstebro

Re: Sortering/prioritering/sammenkædning af store datamængder

Indlæg af js79 »

Jarlen skrev:Jeg tror nu stadig jeg ville smide det ud i flere tabeller. Du skal huske at sætte dine foreign keys på disse forbindelse før det virker. Evt noget á la:

maskintabel
|id|navn | antalRam | RamType |
| 1|Computer1 | 2 | 1 |
| 2|Computer2 | 1 | 3 |

ramtabel
|id|ramNavn|
|1|Kingston|
|2|Unnamed|
|3|etAndetNavn|

Så laver du en foreign key der siger at maskintabel.RamType kun må indeholde muligheder der findes i ramtabel.id
Dette vil give flere fordele, bl.a. slipper du for at gentage navnet på dine ram hele tiden, men det er jo rent pynt.
Den virkelige fordel vil være at det er lettere at finde og sortere maskinerne efter antallet af ram, da der nu er tale om et integer, i stedet for en string. Det er jo på alle måder lettere at sortere:
3, 3, 1
end
3 Kingston, 3 unnamed, 1 kingston
Desuden kan du let og hurtigt udtrække de maskiner der bruger en bestemt ramproducent/type, da du har en foreign key, så når du finder typen i din ramtabel, er det bare at trække alle de computere hvor computer.ramType = ramtabel.id


Jeg har bare stadig et lille problem med at se, at det vil performe bedre end den flade tabel, for så snart man skal finde produkter der fx matcher 10 specifikke komponenter og samtidigt have en sortering, så skal man lave en del opslag i tabellerne.
Jarlen
Indlæg: 834
Tilmeldt: 1. jun 2008, 18:23
IRC nickname: Jarlen
Geografisk sted: København

Re: Sortering/prioritering/sammenkædning af store datamængder

Indlæg af Jarlen »

Hvis du har 10 tabeller á la
|id|komponentnavn|
|1|kingston|
|2|intel|

Vil det være hurtigere at hente 1 id fra hver af 10 tabeller, end at søge igennem 25000 rækker med strings og matche
"kingston|intel|amd|whatever"
jesperjarlskov.dk - Blog om Ubuntu, fri software og andet godt :-)
js79
Indlæg: 124
Tilmeldt: 24. sep 2008, 19:47
Geografisk sted: Holstebro

Re: Sortering/prioritering/sammenkædning af store datamængder

Indlæg af js79 »

Jarlen skrev:Hvis du har 10 tabeller á la
|id|komponentnavn|
|1|kingston|
|2|intel|

Vil det være hurtigere at hente 1 id fra hver af 10 tabeller, end at søge igennem 25000 rækker med strings og matche
"kingston|intel|amd|whatever"


Men nu har jeg jo heller ikke strings til at stå i mine felter, men ja/nej eller 0/1 værdier:

| navn | 1 gb kingston | 2 gb kingston | ...............
| computer 1 | ja | nej | .................
| computer 2 | nej | ja | .................


Derudover var jeg jo også nysgerrig efter et muligt setup, der gør det muligt at liste hvor mange produkter der vil matche næste søgning. Altså hvis man har foretaget en søgning på 10 komponenter og for vist x-antal produkter som matcher disse. Så vil jeg gerne have vist, hvor mange at disse produkter der også matcher på komponent nr 12 eller nr 19.

Et eksempel kan være ligesom edbpriser http://www.edbpriser.dk/Search/Products ... 524&sp=all . Hvis man vælger "Alle filtre", så får man mulighed for at vælge forskellige egenskaber og alt efter hvad man vælger, så bliver de forskellige felter opdateret med hvor mange der nu matcher de nye krav.