[php/mysql] laadscherm bij intensief script

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Na invoeren van gegevens van de gebruiker wordt er een php-script uitgevoerd (met verschillende mysql-queries) die nu al zo'n 0,5 seconden kan duren.

Op dit moment wordt er verder geen gebruik gemaakt van de database, maar als straks de applicatie live is en er vele bezoekers gebruik van zullen maken, kan dat nogal gevolgen hebben lijkt me.

Hoe is te voorkomen dat alles gaat vastlopen bij veel bezoekers? Het is unieke data per gebruiker, dus cachen heeft geen zin. Werkt het om een apart laadscherm te tonen (zoals je weleens bij zoeken ziet op vergelijkingsites), zodat alles op de achtergrond rustig kan worden uitgevoerd?

Acties:
  • 0 Henk 'm!

  • kemphaas
  • Registratie: November 2004
  • Laatst online: 14-09 09:31
Weet niet zo veel van php, maar ik weet wel dat gebruikers snel ongeduldig worden, en dat als gebruikers geen verandering waarnemen, ze denken dat het systeem hangt. Dit is ook de reden dat bijvoorbeeld Microsoft een indicatie geeft van de installatieduur van windows. (Niet dat die indicatie ook maar enigszins klopt, 38 minuten is vaak maar een kwartier, maar als gebruikers iets zien bewegen; tellertje, progress bar, dan zijn ze vaak gerustgesteld dat alles nog werkt.)

Ik zou dus bij iets langere laadtijden zeker een wachtscherm oid maken.

[ Voor 7% gewijzigd door kemphaas op 17-05-2010 14:15 ]

Werk hard als je tijd hebt, dan heb je tijd als je hard moet werken.


Acties:
  • 0 Henk 'm!

  • CRiMiNaL
  • Registratie: Mei 2002
  • Laatst online: 10-01-2024

CRiMiNaL

Witlof ^^

Vastlopen is in deze context niet de juiste omschrijving, immers, het script word wel gewoon uitgevoerd maar de gebruiker krijgt alleen geen feedback.

Over het algemeen is de eerste stap natuurlijk je mysql query's optimaliseren, vooral INSERT statements hoeven niet zoveel tijd te kosten (tenzij je miljoenen records hebt waarbij hij de index gaat bijwerken, maar dat lijkt me hier niet ter sprake)

Er zijn meerdere oplossingen hiervoor, je kunt gebruik maken van PHP's output buffering, hiermee kan je redelijk gemakkelijk een soort van progressbar neerzetten, maar niet alle browsers reageren hier hetzelfde op en vaak zul je ook specifiek per webserver wat configuratie aan moeten passen om het lekker te laten werken.
Een alternatief is het gebruik van AJAX requests waarmee je een bestand / $_SESSION var uitleest waarin je de voortgang bijhoud.

Maargoed, kijk eerst nog eens kritisch naar je query's en je datamodel.

... MMORPG Addict.


Acties:
  • 0 Henk 'm!

  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

Is een laadscherm niet gewoon verbloeming van je onderliggende probleem, dat je script er zo lang over doet om te draaien? Heb je dus al gekeken, naar manieren om de performance van jouw script te verbeteren? Denk dan ook aan je SQL-queries, 5 zijn er volgens mij wel vrij veel, kan je die bijvoorbeeld niet compacter maken en dus sneller? :)

Een AJAX-request om de voortgang weer te geven brengt immers ook weer extra vertraging met zich mee, dus veel schiet je daar ook niet mee op imo.

Acties:
  • 0 Henk 'm!

Verwijderd

Ik wordt zelf erg ongeduldig als ik erachter kom dat het script van de site waar ik op surf helemaal niet stabiel en snel is.
Je kunt eventueel je script wat inkorten zodat het sneller is? gewoon de onnodige dingen removen en misschien in functies terughalen als het niet te missen is? die werken namelijk sneller.

Acties:
  • 0 Henk 'm!

  • YopY
  • Registratie: September 2003
  • Laatst online: 13-07 01:14
CRiMiNaL schreef op maandag 17 mei 2010 @ 14:15:
Maargoed, kijk eerst nog eens kritisch naar je query's en je datamodel.
^. Een progressbar of iets vergelijkbaars toevoegen is leuk, maar je moet wel onthouden dat het slechts het verbloemen van een symptoom is.

[anekdote]
Er was eens een Flash frontend voor een spelletje waar ik aan meegewerkt had. Op een dag zei de opdrachtgever "Zeg, zet er eens een loading indicator voor, zodat mensen het niet te snel weer wegklikken". Zo gezegd, zo gedaan.

Na wat tests bleek dat bij een normaal opgestart spel, het laden tot wel 10 seconden kon duren. Na wat onderzoek bleek dat er per requests mogelijk honderden queries werden uitgevoerd, mede door een slecht geoptimaliseerde manier van het ophalen van afbeeldingen uit het CMS en het ontbreken van goede functionaliteit hiervoor.

Na een flinke optimalisatieslag waarbij de gegevens in één keer opgehaald werden (ipv in drie queries per item, 33 items), en er een eenvoudige in-memory caching werdt toegevoegd (in de vorm van "item", "URL naar afbeelding item" en een andere in de vorm van "dit is het hele ding dat de flash frontend krijgt want dat verandert toch maar eens per maand" werd de laadtijd teruggebracht tot <50 milliseconden, een verbetering van 10.000% of iets in die trant.

Effectief gezien was de progressbar op dat moment slechts in een flits te zien, als hij al zichtbaar was.
[/anekdote]

De wijze les van dit verhaal: Een progressbar is slechts het verbloemen van een probleem. Probeer eerst het probleem op te lossen voordat je een nieuw probleem in de vorm van een progressbar toevoegt.

0.5 seconden is nog niet zoveel overigens. Probeer deze gegevens eens asynchroom op te halen (dwz een pagina die snel inlaadt, en de gegevens die 0.5 seconden duren via AJAX ophalen en weergeven).

Acties:
  • 0 Henk 'm!

  • TheRookie
  • Registratie: December 2001
  • Niet online

TheRookie

Nu met R1200RT

Verwijderd schreef op maandag 17 mei 2010 @ 14:28:
[knip] misschien in functies terughalen als het niet te missen is? die werken namelijk sneller.
sneller dan wat :?

Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Verwijderd schreef op maandag 17 mei 2010 @ 14:28:
Je kunt eventueel je script wat inkorten zodat het sneller is? gewoon de onnodige dingen removen en misschien in functies terughalen als het niet te missen is? die werken namelijk sneller.
Micro optimalisatie en puur gokwerk == zonde van de devtijd.

Als je wilt optimaliseren, moet je eerst meten. Dus verplichte keywords: profilen, slow query log, etc etc.

{signature}


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Er worden op basis van de input flinke berekeningen uitgevoerd, dus de execution time valt best mee. Ik heb dit al zo optimaal mogelijk gemaakt.
Maar waar ik bang voor ben is als 1000 mensen tegelijk dit script zullen gaan uitvoeren de execution time ver boven de halve seconde komt en de database/server wellicht vol- of vastloopt.

Acties:
  • 0 Henk 'm!

  • Freeaqingme
  • Registratie: April 2006
  • Laatst online: 16:20
Dan benchmark je 't toch?

No trees were harmed in creating this message. However, a large number of electrons were terribly inconvenienced.


Acties:
  • 0 Henk 'm!

  • YopY
  • Registratie: September 2003
  • Laatst online: 13-07 01:14
Verwijderd schreef op maandag 17 mei 2010 @ 15:46:
Er worden op basis van de input flinke berekeningen uitgevoerd, dus de execution time valt best mee. Ik heb dit al zo optimaal mogelijk gemaakt.
Maar waar ik bang voor ben is als 1000 mensen tegelijk dit script zullen gaan uitvoeren de execution time ver boven de halve seconde komt en de database/server wellicht vol- of vastloopt.
Dan zou je ervoor moeten zorgen dat die query niet elke keer uitgevoerd wordt. Zijn de gegevens anders bij elk request / voor elke gebruiker? Welke gegevens blijven gedurende welke tijd hetzelfde? Dat zijn zaken die je uit moet zoeken, en als je dat weet kun je gaan kijken naar bepaalde cachingstrategieën. Bijvoorbeeld de resultaten elke 5 minuten of, indien het zeer tijdsgebonden is, elke minuut maar ophalen en in de tussentijd gaan cachen, zodat je niet elke keer bij elk request al die gegevens opnieuw in de DB hoeft te berekenen.

Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
Wellicht een stomme vraag, maar is het realistisch op dit moment dat duizenden mensen tegelijk het script gaan uitvoeren? Kun je verder uitleggen wat je precies moet berekenen/opslaan? Een halve seconde parsetijd voor iets op je eigen systeem is relatief lang namelijk.

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Verwijderd schreef op maandag 17 mei 2010 @ 15:46:
Er worden op basis van de input flinke berekeningen uitgevoerd, dus de execution time valt best mee. Ik heb dit al zo optimaal mogelijk gemaakt.
Maar waar ik bang voor ben is als 1000 mensen tegelijk dit script zullen gaan uitvoeren de execution time ver boven de halve seconde komt en de database/server wellicht vol- of vastloopt.
Bereken je in de database? Dan ga je toch spul redundant opslaan? Bereken je spul in PHP? Dan kan dat ook, maar daar heb je in plaats daarvan ook nog een caching-optie. Waarom zou je bij elke pageview opnieuw alles moeten berekenen?

Verder: een halve seconde op een verder niet gebruikte server duidt toch echt op een behoorlijke berekening danwel foute indices. Heb je hier netjes over nagedacht?

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 01:46
CptChaos schreef op maandag 17 mei 2010 @ 14:25:
Denk dan ook aan je SQL-queries, 5 zijn er volgens mij wel vrij veel, kan je die bijvoorbeeld niet compacter maken en dus sneller? :)
5 queries per request zijn er nog behoorlijk weinig voor een beetje ingewikkelde site. Ik heb applicaties draaien die voor bepaalde complexe overzichtpagina's makkelijk aan 15 ~ 20 queries per pageview zitten en die toch binnen een fractie van een seconde klaar zijn.

Dan: een complexere query is (lang) niet altijd sneller dan twee simpele. Als je bijvoorbeeld een lijst met indici ophaalt en die vervolgens in een where gebruikt kan dit veel sneller zijn dan wanneer je dat in een enkele query doet met een subquery in de where clause (al valt daar natuurlijk wel wat aan te doen door goed te herschrijven) - en dan heb ik het nog niet eens over table locks :)

Een halve seconde is best lang voor een testomgeving, maar hoeft niet per se een probleem te zijn. Als de bottleneck je databaseserver is en je ~0.4 seconden daar aan kwijt bent per pageview impliceert dit dat als er ~20 seconden tussen elke pageview zit je 50 users tegelijk aankan in het meest tijds-optimale geval en mag je dat aantal nog eens vergroten als de queries elkaar niet in de weg zitten en je niet op 100% hardware belasting zit. Daadwerkelijke performance is dan ook lastig te voorspellen, het enige wat je dan ook kan doen is domweg testen en meten.

Een laadscherm is natuurlijk een optie, maar je users gaan er niet altijd blij van worden - de reden waarom je laadschermen bij reissites ziet is doordat die hun gegevens met XML-RPC / SOAP van externe servers halen (dit moet soms zelfs bij bepaalde content providers, zeker in die branche heb ik helaas mogen ondervinden - bijna alle reissites zijn niet meer dan front-ends voor de paar databases die boekingen voor duizenden accomodaties bijhouden) en die requests duren niet zelden serieus lang. Het toepassen als je al je data lokaal hebt zou eigenlijk niet moeten hoeven ;)

[ Voor 3% gewijzigd door FragFrog op 17-05-2010 17:57 ]

[ Site ] [ twitch ] [ jijbuis ]


Acties:
  • 0 Henk 'm!

  • CyBeRSPiN
  • Registratie: Februari 2001
  • Laatst online: 16:29

CyBeRSPiN

sinds 2001

Vrij eenvoudig op te lossen:
begin de output met een <div> die als laadscherm optreedt (met de juiste z-order zodat deze voor je echte content komt te zweven), onderaan je pagina (die komt dus pas aan bij je browser als het script klaar is) zet je dmv Javascript de <div style="display:none"> ;)

Verder eens met hierboven: optimaliseer eerst je queries (met bijv indexes), een laadscherm is ook maar vervelend...

[ Voor 16% gewijzigd door CyBeRSPiN op 19-05-2010 08:39 ]

Pagina: 1