PDA

Bekijk Volledige Versie : Wat zegt dit over de webhoster?



timvermaesen
03/06/12, 16:57
Ik heb een php pagina waarin ik 2 zoekresultaten oproep van 2 databases. Database 1 heeft 2 tabellen met elk bijna een miljoen records (beide samen bijna twee milj), waaronder zinnen. Database 2 heeft ook 2 tabellen met evenveel data als db1, maar hier geen lange zinnen.
Elke database is niet groter dan 50 MB.

De zoekresultaten bestaan uit max zoveel regels (25), en er wordt maar in 1 tabel per database gezocht.

Nu laadt de pagina retetraag, en dus mijn vraag wat dit zegt over de webhoster van mijn shared account. Of zijn mijn databases gewoon veeeeel te zwaar voor een shared account. :nono:

Marcellow
03/06/12, 17:13
Het ligt er helemaal aan hoe de structuur van je tabellen er uit ziet en wat voor query je er op los laat.
Als je bv een SELECT * from table where column1 = '%woord%' op een tabel met een miljoen records los laat,
kan ik me voorstellen dat dat wel eventjes duurt voordat je een antwoord krijgt.

Yourwebhoster
03/06/12, 17:19
Ik heb een php pagina waarin ik 2 zoekresultaten oproep van 2 databases. Database 1 heeft 2 tabellen met elk bijna een miljoen records (beide samen bijna twee milj), waaronder zinnen. Database 2 heeft ook 2 tabellen met evenveel data als db1, maar hier geen lange zinnen.
Elke database is niet groter dan 50 MB.

De zoekresultaten bestaan uit max zoveel regels (25), en er wordt maar in 1 tabel per database gezocht.

Nu laadt de pagina retetraag, en dus mijn vraag wat dit zegt over de webhoster van mijn shared account. Of zijn mijn databases gewoon veeeeel te zwaar voor een shared account. :nono:

Dit is zoals Marcellow aangeeft afhankelijk van de query, de type data, hoe de indexen gemaakt zijn, de cache van de hoster, etc etc etc.. Veel records zorgen er voor dat de server enorm traag kan worden en zoveel records icm complexe queries zijn veelal niet geschikt voor normale shared hosting omgevingen. Je kan ook zelf kijken of je cache in je applicatie kan programmeren, waardoor de resultaten maar één keer binnen de zoveel tijd opgehaald hoeft te worden.

timvermaesen
03/06/12, 17:21
Ik gebruik inderdaad zoiets:
SELECT * FROM tabel WHERE kolom LIKE '%blabla%' ORDER BY RAND() LIMIT 0

Is er dan een betere manier?

Yourwebhoster
03/06/12, 17:25
Ik gebruik inderdaad zoiets:
SELECT * FROM tabel WHERE kolom LIKE '%blabla%' ORDER BY RAND() LIMIT 0

Is er dan een betere manier?

Wat wil je precies bereiken/is het doel van het script?

Klopt het dat je dus een query als deze door 4 miljoen records heen gooit?

timvermaesen
03/06/12, 17:29
Wat wil je precies bereiken/is het doel van het script?

Klopt het dat je dus een query als deze door 4 miljoen records heen gooit?
De pagina bevat zoekresultaten. Een zoekopdracht resulteert dan in een zoektocht in de 2 databases.

En dat is wat ik dus gebruik om de data weer te geven.

systemdeveloper
03/06/12, 17:31
Order by rand() is zóóóóóó fout... (en die limit 0 is een fout neem ik aan?)

Edit: ter info.

Een like '%blabla%' help je index gebruik al om zeep. Daarnaast is order by rand() een 100% performance killer. Mysql moet namelijk eerst je hele tabel scannen omdat je niet kunt indexeren op %blabla%. Daarnaast moet ie ook nog eens random een x aantal records selecteren uit je totale resultset.
Dit kun je niet afschuiven op je hoster maar is puur een programmeursfout.

Edit 2: resultsets zjn tijdelijke tabellen zónder index. Als ze in het ram passen is dat niet altijd zo heel erg, maar met een x mil. records gaat dat geheid naar schijf. Niet vooruit te branden dus.

Yourwebhoster
03/06/12, 17:32
De pagina bevat zoekresultaten. Een zoekopdracht resulteert dan in een zoektocht in de 2 databases.

En dat is wat ik dus gebruik om de data weer te geven.
En waarom dan RAND()?

En idd zoals Systemdeveloper aangeeft limit 0 is zeker een copy/paste foutje, daar was ik min of meer van uit gegaan.

timvermaesen
03/06/12, 17:40
Order by rand() is zóóóóóó fout... (en die limit 0 is een fout neem ik aan?)
SELECT * FROM tabel WHERE kolom LIKE '%blabla%' ORDER BY RAND() LIMIT 0, en hier komt automatisch een getal als limiet van het aantal weer te geven resultaten

Ik ben die Order by rand() eens nader gaan bekijken en het schijnt inderdaad een extra belasting te geven. Erg bedankt om mij hierop te wijzen!

Stewie
03/06/12, 18:05
Jouw doel is alleen om het maximum aantal regels op te vragen, maar waarom vraag je dan de volledige tabel op in plaats van alleen het aantal regels? Staat in de code echt limit 0 of is dat als voorbeeld? In dat eerste geval heeft het geen zin om de resultaten in willekeurige volgorde weer te geven. In de select vraag je tevens alle kolommen op.

systemdeveloper
03/06/12, 18:13
SELECT * FROM tabel WHERE kolom LIKE '%blabla%' ORDER BY RAND() LIMIT 0, en hier komt automatisch een getal als limiet van het aantal weer te geven resultaten

Ik ben die Order by rand() eens nader gaan bekijken en het schijnt inderdaad een extra belasting te geven. Erg bedankt om mij hierop te wijzen!

Dit omschrijven is trouwens geen makkelijke opgave. Wat je eigenlijk moet doen is een join maken met een fictieve tabel waarbij geen order by wordt gedaan, maar waarbij je on the fly de kans berekent dat een record wel/niet geselecteerd wordt. Voorbeelden kun je wel googlen en met wat aanpassingen werkend krijgen. Wij gebruiken het regelmatig voor tabellen met vele miljoenen records.
Het zijn en blijven echter hersenbrekertjes :)

timvermaesen
03/06/12, 18:18
Jouw doel is alleen om het maximum aantal regels op te vragen, maar waarom vraag je dan de volledige tabel op in plaats van alleen het aantal regels? Staat in de code echt limit 0 of is dat als voorbeeld? In dat eerste geval heeft het geen zin om de resultaten in willekeurige volgorde weer te geven. In de select vraag je tevens alle kolommen op.
Dat script gebruik ik al een hele tijd, en mijn doel is voor dat specifieke zoekopdracht maximum 25 regels weer te geven, en dit in random order.

SELECT * FROM 'mijn tabel' WHERE 'mijn kolom' LIKE '%$zoekopdracht%' LIMIT 0, 25 ...en met die BY RAND() zorg ik ervoor dat de weergegeven resultaten voor iedereen anders is, maar steeds relevant.

Nu heb ik gelezen dat die RAND() een probleem geeft voor grote databases, en dat er niet zo maar alternatieven voor handen zijn. Ik ben me hier nu in nog aan het verdiepen...

systemdeveloper
03/06/12, 18:22
Dat script gebruik ik al een hele tijd, en mijn doel is voor dat specifieke zoekopdracht maximum 25 regels weer te geven, en dit in random order.

SELECT * FROM 'mijn tabel' WHERE 'mijn kolom' LIKE '%$zoekopdracht%' LIMIT 0, 25 ...en met die BY RAND() zorg ik ervoor dat de weergegeven resultaten voor iedereen anders is, maar steeds relevant.

Nu heb ik gelezen dat die RAND() een probleem geeft voor grote databases, en dat er niet zo maar alternatieven voor handen zijn. Ik ben me hier nu in nog aan het verdiepen...

Je eerste probleem is de like '%---

Door dat eerste % kan je index al niet meer gebruikt worden. Let wel.. het % op het einde is geen probleem.
Het beste kun je dit deel oplossen met een 'match against' en een fulltext index.
De rand() moet je oplossen zoals ik zei als je het goed wilt doen, maar uiteraard kun je je ook limiteren tot bv de laatste 10-20-30k records. Voor de user is dat meestal random genoeg.

davinci
03/06/12, 18:41
als je perse random wil. kan je natuurlijk ook (in php) gaan voor iets als.



<?php
//even snel
$start=rand(0,1000000-25); // er vanuitgaand dat er precies 1000000 rijen zijn.
$sql="SELECT id FROM table WHERE col='bla' LIMIT ".$start.", 25";

systemdeveloper
03/06/12, 18:53
als je perse random wil. kan je natuurlijk ook (in php) gaan voor iets als.



<?php
//even snel
$start=rand(0,1000000-25); // er vanuitgaand dat er precies 1000000 rijen zijn.
$sql="SELECT id FROM table WHERE col='bla' LIMIT ".$start.", 25";


Nee, dat kan niet (om minimaal 2 redenen) maar ook daar zit je met het probleem dat de mysql resultset tot aan het $start moet worden weggegooid (aan de serverkant).

timvermaesen
03/06/12, 19:05
En stel dat ik de grote database in 5 kleinere databases verdeel met elk 200.000 regels. Kan het zoeken in deze 5 delen een betere load geven, ipv zoeken in 1 grote database? Gewoon een gedachte...

systemdeveloper
03/06/12, 19:09
En stel dat ik de grote database in 5 kleinere databases verdeel met elk 200.000 regels. Kan het zoeken in deze 5 delen een betere load geven, ipv zoeken in 1 grote database? Gewoon een gedachte...

Nee, niet zolang het 1 server blijft. Daarnaast heb je dan meer overhead met het opzetten van connecties (wat 1 van de traagste dingen is) en je lost het probleem niet op. Als je het de queries achter elkaar uitvoert heb je hooguit het profijt dat de mysqlserver minder ram verbruikt, maar als geheel zal het waarschijnlijk niet sneller worden, maar je wel meer werk opleveren.

SF-Jeroen
03/06/12, 19:09
Dat is denk ik ook niet gewenst, omdat je dan meerdere database verbindingen moet gaan maken. Bovendien zou een DB van 50 mb toch geen probleem moeten geven in MySQL. Ik neem aan dat je wel netjes indexes gebruikt?

Ik zou altijd in eerste instantie gaan kijken of je de code kunt verbeteren (zowel PHP als MySQL). Als het dan nog traag blijft zou je kunnen overstappen naar een VPS en zelf gaan spelen met de my.cnf instellingen en eventueel aan mysql caching gaan doen.

timvermaesen
03/06/12, 19:51
Dat is denk ik ook niet gewenst, omdat je dan meerdere database verbindingen moet gaan maken. Bovendien zou een DB van 50 mb toch geen probleem moeten geven in MySQL. Ik neem aan dat je wel netjes indexes gebruikt?

Ik zou altijd in eerste instantie gaan kijken of je de code kunt verbeteren (zowel PHP als MySQL). Als het dan nog traag blijft zou je kunnen overstappen naar een VPS en zelf gaan spelen met de my.cnf instellingen en eventueel aan mysql caching gaan doen.
Ik importeer enkel data in een .ods naar de database. Eerlijk gezegd heb ik nooit iets met indexes gedaan. :o Ik ben dit nu nader aan het bekijken...Bedankt!

davinci
03/06/12, 20:06
Nee, dat kan niet (om minimaal 2 redenen) maar ook daar zit je met het probleem dat de mysql resultset tot aan het $start moet worden weggegooid (aan de serverkant).

Hier stond iets doms..

En ja je hebt gelijk. :)

timvermaesen
03/06/12, 20:31
Ik heb het volgende gedaan:


CREATE INDEX indx
ON data (resul)

Ik heb dus een index gecreeërd voor kolom 'resul' in tabel 'data'. Ik heb de kolom 'resul' van een index voorzien, omdat daarin gezocht wordt.

Dit is hetgeen bedoelt wordt met werken met indexes?

systemdeveloper
03/06/12, 21:26
Ik heb het volgende gedaan:


CREATE INDEX indx
ON data (resul)

Ik heb dus een index gecreeërd voor kolom 'resul' in tabel 'data'. Ik heb de kolom 'resul' van een index voorzien, omdat daarin gezocht wordt.

Dit is hetgeen bedoelt wordt met werken met indexes?

Dat is wat bedoelt wordt met indexen, maar er zit iets meer achter dan alleen een create index aankicken. Het gaat een beetje te ver om dat uit te leggen, zeker als je ze nog nooit gebruikt hebt.

Je kunt wel zien of je index effect heeft door 'EXPLAIN' voor je query te zetten en deze in bv. phpmyadmin uit te voeren. Je kunt dan zien of je query de index ook daadwerkelijk gebruikt.

Marcellow
03/06/12, 21:45
Een index zal met een like niet gaan werken ben ik bang....

systemdeveloper
03/06/12, 22:16
Een index zal met een like niet gaan werken ben ik bang....

Had ik ook al gezegd, maar wie niet horen wil ;)

timvermaesen
04/06/12, 01:49
Ik denk dat ik mijn probleem opgelost heb, want de database gaat supersnel! Ik heb met de tips hier en elders de index kunnen laten samenwerken met een like, door simpelweg de eerste % weg te laten. Het ging van 4-20 sec naar 1 sec of minder.

Erg bedankt! :thumbup:

davinci
04/06/12, 08:17
heb je uberhaupt wel een LIKE statement nodig dan?

systemdeveloper
04/06/12, 08:42
Ik denk dat ik mijn probleem opgelost heb, want de database gaat supersnel! Ik heb met de tips hier en elders de index kunnen laten samenwerken met een like, door simpelweg de eerste % weg te laten. Het ging van 4-20 sec naar 1 sec of minder.

Erg bedankt! :thumbup:

Goed dat het gelukt is, maar je verandert wel de funktionaliteit nu. Zoeken op like '%blabla%' is niet gelijk aan zoeken op 'blabla%' ;)

Yourwebhoster
04/06/12, 09:59
Ik denk dat ik mijn probleem opgelost heb, want de database gaat supersnel! Ik heb met de tips hier en elders de index kunnen laten samenwerken met een like, door simpelweg de eerste % weg te laten. Het ging van 4-20 sec naar 1 sec of minder.

Erg bedankt! :thumbup:

Je weet wel dat elke record moet beginnen met blabla als je LIKE 'blabla%' doet en niet in de hele record zoekt voor de term blabla?