PHP en result caching db

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Reveal!
  • Registratie: November 1999
  • Laatst online: 20:50
Hoe kun je met PHP en MySQL het volgende scenario bewerkstelligen ?

Je doet een query op een set data, deze set data wil je vervolgens actief gaan filteren.
Dus zeg ik heb een query met result 1.000.000 users, nu wil ik deze users vervolgens gaan filteren op geslacht, vervolgens op leeftijd en daarna kleur haar etc etc.

Hoe kan ik deze filteren op leeftijd zonder dat ik elke keer opnieuw de query naar de database hoef te sturen.
Het liefst dat ik gewoon weer een select kan doen maar dit keer tegen een cache.

Ik heb gekeken naar APC maar volgens mij kan APC alleen de dataset storen, dus dan zou ik me result array moeten serializen en unserializen en vervolgens met de array gaan werken.
Ik zou met APC niet gewoon kunnen query'n tegen me voorgaande results.

Is dit wat ik zoek mogelijk met een cache (misschien memcached?) of moet ik meer in de hoek van ORM gaan kijken ?

Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

Waarom wil je dit? Een miljoen records is peanuts voor een database server als je maar je indexes goed hebt staan. Daar kun je rustig een paar queries op loslaten.

'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!

  • Reveal!
  • Registratie: November 1999
  • Laatst online: 20:50
Dat is ook zo, maar het is een query die ook een heleboel joins heeft.
En hij zou erg vaak aangeroepen moeten worden.

Acties:
  • 0 Henk 'm!

Verwijderd

Goed normaliseren, de juiste indexes zetten en gaan met die banaan. Je kunt het echt niet beter optimaliseren dan de MySQL zelf al kan.

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Tja, wat wil je precies hebben?

- Een situatie dat je steeds je query's uitbreidt en dat deze handig gecached worden, dan gewoon mysql indexen gebruiken...
- Een situatie dat je 1 query hebt, dat die resultset gecached wordt en dat je er dan in je code overheen itereert , kijk dan eens naar een ADODB oid maar bedenk wel goed of mysql dit niet gewoon beter kan doen....

Acties:
  • 0 Henk 'm!

  • cariolive23
  • Registratie: Januari 2007
  • Laatst online: 18-10-2024
Reveal! schreef op zaterdag 22 augustus 2009 @ 18:21:
Dat is ook zo, maar het is een query die ook een heleboel joins heeft.
Dat is mooi, wanneer je die goed gebruikt en dus een handige query opzet, is het appeltje-eitje voor de database om e.e.a. op te lepelen.

Gebruik EXPLAIN om te achterhalen hoe e.e.a. door de database wordt uitgevoerd, welke indexen er eventueel bruikbaar zijn en welke indexen daadwerkelijk worden gebruikt. Ga vervolgens de boel optimaliseren.

Wanneer je veel RAM gebruikt voor de queries, kan het noodzakelijk zijn om een betere configuratie op te zetten. Anders kan het met grote datasets gebeuren dat de database moet gaan swappen en dat is natuurlijk zo snel als dikke poep door een heel dun trechtertje...

Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

cariolive23 schreef op zaterdag 22 augustus 2009 @ 19:04:
[...]

Anders kan het met grote datasets gebeuren dat de database moet gaan swappen en dat is natuurlijk zo snel als dikke poep door een heel dun trechtertje...
...maar dat gaat je bij een tabel met een miljoen usertjes niet gauw lukken tenzij je maar een paar MB RAM tot je beschikking hebt. ;)

'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!

  • Reveal!
  • Registratie: November 1999
  • Laatst online: 20:50
NMe schreef op zaterdag 22 augustus 2009 @ 21:26:
[...]

...maar dat gaat je bij een tabel met een miljoen usertjes niet gauw lukken tenzij je maar een paar MB RAM tot je beschikking hebt. ;)
Die miljoen users was ook maar een voorbeeld, maar goed we gaan is kijken hoe het gaat.
Het leek mij alleen veel sneller om tegen een cache te query'n dan tegen de database zelf.

Zeker als het om vele query's/bezoekers tegelijk gaat die aan het filteren gaan.
Een bestaande result set filteren lijkt me sneller dan elke keer weer opnieuw de result set op te bouwen.

Acties:
  • 0 Henk 'm!

  • cariolive23
  • Registratie: Januari 2007
  • Laatst online: 18-10-2024
NMe schreef op zaterdag 22 augustus 2009 @ 21:26:
...maar dat gaat je bij een tabel met een miljoen usertjes niet gauw lukken tenzij je maar een paar MB RAM tot je beschikking hebt. ;)
En over hoeveel RAM zal de gemiddelde sessie beschikken bij shared hosting? Ik vrees dat minstens 95% van de hostingproviders (ik ben optimistisch!) nauwelijks iets aan configuratie heeft gedaan en dat je dus ook nauwelijks over het RAM kunt beschikken. Ik weet zo niet wat MySQL standaard gebruikt, maar dat zal vast niet zo heel erg veel zijn. Wellicht kun je dit runtime nog aanpassen, kun je wat extra RAM meepakken voor die situaties dat je dat nodig hebt.

Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

Reveal! schreef op zondag 23 augustus 2009 @ 12:56:
[...]

Die miljoen users was ook maar een voorbeeld, maar goed we gaan is kijken hoe het gaat.
Het leek mij alleen veel sneller om tegen een cache te query'n dan tegen de database zelf.

Zeker als het om vele query's/bezoekers tegelijk gaat die aan het filteren gaan.
Een bestaande result set filteren lijkt me sneller dan elke keer weer opnieuw de result set op te bouwen.
Je zegt "tegen een cache queriën". Je wil dus alleen de joins in een soort tijdelijke tabel cachen? Dat gaat je erg weinig verschil opleveren bij een goed genormaliseerde database met de goeie indexen. Ik denk dat je, wanneer dat een probleem wordt, beter even kan kijken naar het cachen van complete pagina's in plaats van queries. Al zal query caching vast ook goed genoeg zijn in de meeste gevallen.

'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!

Verwijderd

Wat heeft PHP of een sessie met de hoeveelheid RAM die MySQL tot zijn beschikking heeft te maken? MySQL draait als een losse service, niet als child process van een Apache thread ofzo.

Maar goed, dit topic is weer een typisch voorbeeld van iemand die wil gaan optimaliseren voordat er überhaupt een probleem is geconstateerd. MySQL doet ook nog aan query caching als dat een beetje normaal is geconfigureerd.

Acties:
  • 0 Henk 'm!

  • Reveal!
  • Registratie: November 1999
  • Laatst online: 20:50
NMe schreef op zondag 23 augustus 2009 @ 13:26:
[...]

Je zegt "tegen een cache queriën". Je wil dus alleen de joins in een soort tijdelijke tabel cachen? Dat gaat je erg weinig verschil opleveren bij een goed genormaliseerde database met de goeie indexen. Ik denk dat je, wanneer dat een probleem wordt, beter even kan kijken naar het cachen van complete pagina's in plaats van queries. Al zal query caching vast ook goed genoeg zijn in de meeste gevallen.
Het enige probleem met de query cache en de volle pagina's cachen is dat de query's exact hetzelfde moeten zijn.
Wat wij willen met de resultset de resultaten steeds verder filteren, elke filter of WHERE statement zou dan weer een nieuwe query zijn en om te gebruiken van de cache zou de gebruiker de filters dus ook altijd in exact dezelfde volgorde moeten kiezen als iemand anders.

Voorbeeld,
Stel je heb weer de users en je kiest mannen en daarna dan met zwart haar.
En iemand anders kiest mensen met zwart haar en ze moeten ook man zijn.

Dat zijn verschillende query's en maken dus geen gebruik van de cache.

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Reveal! schreef op zondag 23 augustus 2009 @ 14:36:
[...]
Het enige probleem met de query cache en de volle pagina's cachen is dat de query's exact hetzelfde moeten zijn.
...
en om te gebruiken van de cache zou de gebruiker de filters dus ook altijd in exact dezelfde volgorde moeten kiezen als iemand anders.
Yep, kan je bereiken door gewoon je query's altijd hetzelfde op te bouwen.
Voorbeeld,
Stel je heb weer de users en je kiest mannen en daarna dan met zwart haar.
En iemand anders kiest mensen met zwart haar en ze moeten ook man zijn.

Dat zijn verschillende query's en maken dus geen gebruik van de cache.
Ok, dan heb je dus 4 mogelijke query's
1 : Alle users ( keuze user 1+2 )
2 : Alle users die man zijn ( keuze user 1 )
3 : Alle users met zwart haar ( keuze user 2 )
4 : Alle users die man zijn en zwart haar hebben ( keuze user 1 +2 )

50% komt nu dus al uit je querycache...

Alle users die man zijn en zwart haar hebben vs alle users met zwart haar die man zijn levert dezelfde resultset op, dus als je de query in dezelfde volgorde opbouwt gebruikt het ook de querycache.

Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Kap eens met over caches te blaten.

Denk na over hoe je precies wilt filteren en implementeer dat. Evalueer vervolgens op basis van je implementatie en een realistische set gegevens of je uberhaupt een performance probleem hebt en hoe je dat dan misschien aan zou moeten pakken. :)

{signature}


Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Voutloos schreef op zondag 23 augustus 2009 @ 15:02:
Kap eens met over caches te blaten.
Waarom? Je FS heeft een gratis cache, je DB heeft een gratis cache.
Het is enkel hoe handig gebruik ervan te maken, dat is idd een kwestie van evalueren en testen etc.

Acties:
  • 0 Henk 'm!

Verwijderd

Gomez12 schreef op zondag 23 augustus 2009 @ 15:15:

Waarom? Je FS heeft een gratis cache, je DB heeft een gratis cache.
Het is enkel hoe handig gebruik ervan te maken, dat is idd een kwestie van evalueren en testen etc.
Ik vermoed dat Voutloos het tegen Reveal! had. :)
Verder weinig toe te voegen. De topicstarter moet maar eens eerst zijn applicatie maken. Alsof het veel werk is de backend later iets te optimaliseren mocht dat nodig blijken.

Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
En vaak wordt een LRU strategie gebruikt bij caches, dus als je dat weet, kun je er je voordeel mee doen. Maar indexeren is het sleutelwoord, en dat stond al in de eerste reply :)

[ Voor 207% gewijzigd door GlowMouse op 23-08-2009 15:22 ]


Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

Reveal! schreef op zondag 23 augustus 2009 @ 14:36:
[...]

Voorbeeld,
Stel je heb weer de users en je kiest mannen en daarna dan met zwart haar.
En iemand anders kiest mensen met zwart haar en ze moeten ook man zijn.

Dat zijn verschillende query's en maken dus geen gebruik van de cache.
Ehm...ben ik nu de enige die dit gek vindt? Waarom zit je tussendoor te queryen als de gebruiker zijn filters nog niet helemaal ingesteld heeft? En zelfs al doe je het zo, dan zal een beetje DBMS (al weet ik niet of MySQL daar ook onder valt) SELECT * WHERE a = b AND x = y echt wel hetzelfde opvatten als SELECT * WHERE x = y AND a = b. ;)

'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!

  • Jory
  • Registratie: Mei 2006
  • Laatst online: 18-09 11:49
Het enige dat ik me daar bij voor kan stellen, is dat je als gebruiker gaat zoeken naar andere gebruikers en daarbij je criteria steeds verder beperkt.
Dus jij als gebruiker wil eerst een lijst van alle mannen. Daarna wil je uit die lijst alleen de mannen met zwart haar zien. En daarna moeten uit die lijst nog eens alleen diegene met bruine ogen getoond worden. (Klinkt als een brakke UI als het alleen zo kan trouwens - ik wil gewoon meteen precies kunnen ingeven wat ik wil zien. :) )
Als het inderdaad zo werkt, is het dus bij iedere page view een nieuwe query. Geen probleem toch?

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
NMe schreef op zondag 23 augustus 2009 @ 17:38:
[...]

Ehm...ben ik nu de enige die dit gek vindt? Waarom zit je tussendoor te queryen als de gebruiker zijn filters nog niet helemaal ingesteld heeft? En zelfs al doe je het zo, dan zal een beetje DBMS (al weet ik niet of MySQL daar ook onder valt) [font=mono]SELECT * WHERE a = b AND x = y[/] echt wel hetzelfde opvatten als [font=mono]SELECT * WHERE x = y AND a = b[/]. ;)
Tussentijdse weergave van geselecteerde filters...

Als ik bij mannen nog maar 10 resultaten overhoud hoef ik niet perse door te zoeken naar zwart haar ( misschien is donkerbruin ook goed genoeg ) maar heb ik 10.000 resultaten over dan wil ik verder filteren...

En het dbms van mysql vat die query's afaik hetzelfde op, de querycache van mysql echter niet...

Simpel trucje is om in je db-layer je statement volgorde altijd hetzelfde op te bouwen dan profiteer je ook nog eens van de gratis querycache
Jory167 schreef op zondag 23 augustus 2009 @ 17:55:
Dus jij als gebruiker wil eerst een lijst van alle mannen. Daarna wil je uit die lijst alleen de mannen met zwart haar zien. En daarna moeten uit die lijst nog eens alleen diegene met bruine ogen getoond worden. (Klinkt als een brakke UI als het alleen zo kan trouwens - ik wil gewoon meteen precies kunnen ingeven wat ik wil zien. :) )
Als het inderdaad zo werkt, is het dus bij iedere page view een nieuwe query. Geen probleem toch?
Met een beetje handig ge-ajax etc kan je in 1x opgeven wat je zoekt en je kan tussentijds de resultaten bekijken, gewoon bovenin de filter boxen zetten en onderin de results, ajax requests vuur je pas af na x tijd niets gedaan

[ Voor 28% gewijzigd door Gomez12 op 23-08-2009 19:00 ]


Acties:
  • 0 Henk 'm!

  • Reveal!
  • Registratie: November 1999
  • Laatst online: 20:50
Wat bedoel je precies met altijd je statement hetzelfde opbouwen ?
Je bent toch afhankelijk van hoe je gebruiker de filters kiest ?
En inderdaad SQL Cache vat het als verschillende queries op en maakt er dus ook nieuwe caches voor aan.

Verder werkt de betreffende site inderdaad zoals je zegt.

Het voordeel van filters on the fly ten opzichte van vooraf gezette waardes, is dat je ten alle tijden kan zien wat voor invloed elke filter op je resultaten heeft.

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Tip : Let er goed op dat je je ajax requests pas na een tijdje inactiviteit van de gebruiker ( en niet te weinig ) afvuurt, voor je het weet creeer je je eigen DOS doordat enkele gebruikers gewoon wat rondklikken...

En je sql volgorde/opbouw is totaal niet afhankelijk van hoe de gebruiker de filters kiest.
Zolang je geen directe gebruikersinput in je sql statements gooit bouw je ze zelf op dus kan je er ook zelf een volgorde aan geven ( en zorgen dat deze altijd gelijk is ).

Volgorde is enkel zo simpel als : als iemand in een filter man heeft gekozen dan staat dit altijd als 1e statement, 2e statement ( indien het geslacht aanwezig is, anders het 1e statement ) is altijd de haarkleur etc. etc.

Gewoon je sql statement in een bepaalde vaste volgorde opbouwen en niet willekeurig de volgorde van de gebruiker volgen...

Acties:
  • 0 Henk 'm!

  • cariolive23
  • Registratie: Januari 2007
  • Laatst online: 18-10-2024
Verwijderd schreef op zondag 23 augustus 2009 @ 13:26:
Wat heeft PHP of een sessie met de hoeveelheid RAM die MySQL tot zijn beschikking heeft te maken? MySQL draait als een losse service, niet als child process van een Apache thread ofzo.
Een connectie met de database wordt ook wel een sessie genoemd. Dat heeft op zich niks met PHP te maken, iedere applicatie en/of taal kan een database sessie (connectie zo je wilt) aanmaken met jouw MySQL-database. En uiteraard draait de database als een aparte service, maar wel eentje die RAM nodig heeft. Sterker nog, databases zijn gek op RAM! En dus moet je de boel fatsoenlijk configureren.

Volgens mij verwar je e.e.a. met $_SESSION, daar heeft een database sessie niets mee te maken. Hoewel, die kun je ook weer in databases afhandelen, maar dat is weer een ander verhaal.

Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
1. Je gebruikte zelf het woord sessie het eerst. B) 2. Cheatah weet wel waar hij het over heeft. :P

Dit topic gaat nog steeds nergens over. Ik zie nog steeds geen explain, meetdata of analyse met een profiler langskomen. Iedereen is als een kip zonder kop aan het kletsen over bepaalde optimalisatiedetails die wellicht heel er leuk zijn, maar toch wel erg op de zaken vooruit lopen. :z

{signature}


Acties:
  • 0 Henk 'm!

  • cariolive23
  • Registratie: Januari 2007
  • Laatst online: 18-10-2024
Configureren van de sessie in MySQL:
SQL:
1
SET SESSION sort_buffer_size=1000000;

Van belang wanneer uit de EXPLAIN blijkt dat je geheugen tekort komt bij het uitvoeren van de query, ondanks dat er voldoende RAM in de server beschikbaar is.

Acties:
  • 0 Henk 'm!

  • jbdeiman
  • Registratie: September 2008
  • Laatst online: 18:00
Wat ook goed mogelijk is is om standaard alleen de aantallen te laten zien die aan je voorwaarden voldoen.
Stel dat je alle mannen wilt en dat zijn er 570.000 van de 1.000.000, dan geef je het getal 570.000 weer op een handige locatie.

Iemand die wil gaan zoeken weet dan dat hij/ zij verder moet gaan filteren, omdat het voor hemzelf geen doen is die resultaten te doorlopen. Blijven er bij mannen met zwarte haren nog maar 100 over, dan kan de bezoeker ervoor kiezen deze resultaten weer te geven (tip: gebruik wel paginering, niet allen 100 op 1 pagina) en te doorzoeken.

Je kunt zelfs de "submit knop" blokkeren bij te hoge aantallen resultaten of bij klikken op de knop bij teveel resultaten een melding geven. Mogelijkheden zat, duidelijk voor je gebruikers.

Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

jbdeiman schreef op maandag 24 augustus 2009 @ 09:35:
Je kunt zelfs de "submit knop" blokkeren bij te hoge aantallen resultaten of bij klikken op de knop bij teveel resultaten een melding geven. Mogelijkheden zat, duidelijk voor je gebruikers.
Ehm, om te weten dat die aantallen te hoog zijn moet je toch al eerst queryen? Je optimaliseert dan toch, niks, behalve hooguit je user interface? :?

Laten we nu maar eens ophouden met het bij elkaar verzamelen van allerlei obscure micro-optimalisaties totdat uiteindelijk blijkt dat het echt nodig is. Ik ben het met Voutloos eens dat dit hele topic geen zin heeft zonder een EXPLAIN van de query om te zien wat er nou gebeurt bij het uitvoeren van een query en belangrijker: of dat caching en al die andere minuscule verbeterinkjes écht rechtvaardigt. :)

'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!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 16-09 09:15

Janoz

Moderator Devschuur®

!litemod

NMe schreef op maandag 24 augustus 2009 @ 15:13:
Ehm, om te weten dat die aantallen te hoog zijn moet je toch al eerst queryen? Je optimaliseert dan toch, niks, behalve hooguit je user interface? :?
Niet helemaal mee eens. Ja, je moet queryen, maar een count query die 1 integer oplevert is wel wat optimaler dan het compleet opbouwen van een enorme resultset.
Laten we nu maar eens ophouden met het bij elkaar verzamelen van allerlei obscure micro-optimalisaties totdat uiteindelijk blijkt dat het echt nodig is. Ik ben het met Voutloos eens dat dit hele topic geen zin heeft zonder een EXPLAIN van de query om te zien wat er nou gebeurt bij het uitvoeren van een query en belangrijker: of dat caching en al die andere minuscule verbeterinkjes écht rechtvaardigt. :)
Daar ben ik het dan vervolgens wel weer grondig mee eens.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'

Pagina: 1