abonnement Unibet Coolblue Bitvavo
  donderdag 1 januari 2009 @ 21:04:49 #151
75592 GlowMouse
l'état, c'est moi
pi_64564579
Cachen inderdaad
eee7a201261dfdad9fdfe74277d27e68890cf0a220f41425870f2ca26e0521b0
pi_64564814
quote:
Op donderdag 1 januari 2009 21:04 schreef GlowMouse het volgende:
Cachen inderdaad
Dat idd. En MySQL heeft ook een functie die het leven wat makkelijker kan maken.
pi_64566959
quote:
Op donderdag 1 januari 2009 20:55 schreef Likkende_Lassie het volgende:
Helaas vind ik hem daar niet tussen, maar heb al een goed alternatief kunnen vinden.

Andere vraag:

Ik heb een array uit een database met allemaal producten.
Nu geef ik de klant de mogelijkheid te filterten op a tm z, welke bovenaan de pagina staan als volgt:

bekijk alle producten - A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

Nu is het niet altijd zo dat er onder G iets te vinden is, enz. In zo'n geval wil ik G als onklikbaar instellen.
Nu kan ik natuurlijk een while loop maken en indien er geen product met de beginletter G wordt gevonden, iets uitvoeren. Maar als er veel producten in de array zitten, wordt het misschien toch iets te traag.

Bijkomend probleem is, dat als er een letter is gekozen, de array slechts alleen producten bevat die beginnen met de gekozen letter... misschien een idee om de beschikbare letters ergens op te slaan?
Ik zou zeer zeker neit gaan opslaan welke letters een product bevatten tenzij de producten stabiel zijn en er maar weinig nieuwe producten bijkomen/weggaan/veranderen van naam.

Wat je kan doen is je producten opslaan in een dictioary (2d array) van letters naar arrays van producten. Dus
$producten["a"][0] geeeft het eerst product dat met een a begint.
Zo kan je met een count($producten["x"]); zien hoeveel producten er zijn die met letter x beginnen.
  donderdag 1 januari 2009 @ 22:20:38 #154
75592 GlowMouse
l'état, c'est moi
pi_64567125
quote:
Op donderdag 1 januari 2009 22:16 schreef Database het volgende:
Ik zou zeer zeker neit gaan opslaan welke letters een product bevatten tenzij de producten stabiel zijn en er maar weinig nieuwe producten bijkomen/weggaan/veranderen van naam.
Waarom niet? Hoe denk je dat de verhouding opvragen/aanpassen is?
quote:
Wat je kan doen is je producten opslaan in een dictioary (2d array) van letters naar arrays van producten. Dus $producten["a"][0] geeeft het eerst product dat met een a begint.
Zo kan je met een count($producten["x"]); zien hoeveel producten er zijn die met letter x beginnen.
Hoe denk je dat dat werkt als er, zeg, 10.000 producten zijn?
eee7a201261dfdad9fdfe74277d27e68890cf0a220f41425870f2ca26e0521b0
pi_64568726
quote:
Op donderdag 1 januari 2009 22:20 schreef GlowMouse het volgende:

[..]

Waarom niet? Hoe denk je dat de verhouding opvragen/aanpassen is?
Omdat dit een bron is van bugs. Je krijgt hier code van wat slecht onderhoudbaar is omdat je moet weten/onthouden dat wanneer je een de naam van een product wijzigt, een nieuw product toevoegt of een product verwijderd, dat je dan ook je extra tabel moet updaten. Normaal gesproken is het gewoon bad practice. Plus dat het queryen van een database veel meer overhead geeft dan code uitvoeren.
quote:
Hoe denk je dat dat werkt als er, zeg, 10.000 producten zijn?
Ik snap niet wat je bedoelt? Het opbouwen van je dictioary kost lineair meer werk met het aantal producten dat je hebt.
Een specifiek item opzoeken gaat sneller als je de productnaam weet (omdat het aantal items wat je dan moet doorzoeken ongeveer 1/26ste is vergeleken bij een lange een dimensionale array). En aangezien je maar 1 keer opbouwt en waarschijnlijk meerdere keer opzoekt, zie ik - met alle respect - het probleem van 10.000 producten niet.
pi_64569147
quote:
Op donderdag 1 januari 2009 23:11 schreef Database het volgende:

[..]

Omdat dit een bron is van bugs. Je krijgt hier code van wat slecht onderhoudbaar is omdat je moet weten/onthouden dat wanneer je een de naam van een product wijzigt, een nieuw product toevoegt of een product verwijderd, dat je dan ook je extra tabel moet updaten. Normaal gesproken is het gewoon bad practice. Plus dat het queryen van een database veel meer overhead geeft dan code uitvoeren.
[..]

Ik snap niet wat je bedoelt? Het opbouwen van je dictioary kost lineair meer werk met het aantal producten dat je hebt.
Een specifiek item opzoeken gaat sneller als je de productnaam weet (omdat het aantal items wat je dan moet doorzoeken ongeveer 1/26ste is vergeleken bij een lange een dimensionale array). En aangezien je maar 1 keer opbouwt en waarschijnlijk meerdere keer opzoekt, zie ik - met alle respect - het probleem van 10.000 producten niet.
True. Dit pattern zie je wel vaker bij grote datacollecties.
  donderdag 1 januari 2009 @ 23:44:14 #157
75592 GlowMouse
l'état, c'est moi
pi_64569596
quote:
Ik snap niet wat je bedoelt? Het opbouwen van je dictioary kost lineair meer werk met het aantal producten dat je hebt.
Een specifiek item opzoeken gaat sneller als je de productnaam weet (omdat het aantal items wat je dan moet doorzoeken ongeveer 1/26ste is vergeleken bij een lange een dimensionale array). En aangezien je maar 1 keer opbouwt en waarschijnlijk meerdere keer opzoekt, zie ik - met alle respect - het probleem van 10.000 producten niet.
Het probleem is dat je dat lineair meer tijdrovende klusje op jouw manier bij elke request moet doen. Ten eerste moet de gebruiker langer wachten, ten tweede krijgt je server een probleem als je wat meer bezoekers krijgt.

Bij een request wil je gewoon snel de producten hebben die alleen met een bepaalde beginletter beginnen, eventueel ook alleen die op een bepaalde pagina voorkomen als je paginering gebruikt. Die andere producten wil je niet eerst in een arraytje stoppen, je wilt gewoon snel weten of ze bestaan. En als bij het groeien van je dataset de rekentijd lineair toeneemt, wil je gewoon dingen cachen als je op den duur ook daadwerkelijk veel producten krijgt, bijna onafhankelijk tegen welke prijs.
eee7a201261dfdad9fdfe74277d27e68890cf0a220f41425870f2ca26e0521b0
pi_64570282
quote:
Op donderdag 1 januari 2009 23:11 schreef Database het volgende:

[..]

Omdat dit een bron is van bugs. Je krijgt hier code van wat slecht onderhoudbaar is omdat je moet weten/onthouden dat wanneer je een de naam van een product wijzigt, een nieuw product toevoegt of een product verwijderd, dat je dan ook je extra tabel moet updaten. Normaal gesproken is het gewoon bad practice. Plus dat het queryen van een database veel meer overhead geeft dan code uitvoeren.
In het kader van normalisatie is het idd niet handig om informatie dubbel op te slaan. Aan de andere kant is het ook weer niet zo dat je moet onthouden wat er allemaal moet gebeuren bij het aanpassen/toevoegen/verwijderen van een product. Daar kun je immers een leuke API voor schrijven. (En als je dat goed doet, kun je naderhand de hele opbouw aanpassen zonder elders in de code te moeten rommelen.)
quote:
[..]

Ik snap niet wat je bedoelt? Het opbouwen van je dictioary kost lineair meer werk met het aantal producten dat je hebt.
Een specifiek item opzoeken gaat sneller als je de productnaam weet (omdat het aantal items wat je dan moet doorzoeken ongeveer 1/26ste is vergeleken bij een lange een dimensionale array). En aangezien je maar 1 keer opbouwt en waarschijnlijk meerdere keer opzoekt, zie ik - met alle respect - het probleem van 10.000 producten niet.
Ik denk dat het aantal zoekacties laag is. Het blijft wel PHP, dus aan het eind van het script is al je harde werk verloren gegaan. De kans dat je meer dan 1 keer gaat zoeken lijkt me dan niet zo groot. En als je een lijst wilt hebben van alle beginletters en van alle producten die met de letter C beginnen, dan is het wat overkill om alle producten uit de database te trekken.
pi_64570319
quote:
Op donderdag 1 januari 2009 23:26 schreef Scorpie het volgende:

[..]

True. Dit pattern zie je wel vaker bij grote datacollecties.
Gebruiken die ook PHP/MySQL?
pi_64574816
quote:
Op donderdag 1 januari 2009 21:12 schreef Light het volgende:

[..]

Dat idd. En MySQL heeft ook een functie die het leven wat makkelijker kan maken.
Dat lijkt mij inderdaad een goede oplossing:

1SELECT DISTINCT(SUBSTRING(product, 1, 1)) FROM producten
  vrijdag 2 januari 2009 @ 13:07:49 #161
12221 Tijn
Powered by MS Paint
pi_64575600
quote:
Op vrijdag 2 januari 2009 00:17 schreef Light het volgende:

[..]

Gebruiken die ook PHP/MySQL?
Er zijn genoeg grote websites met flinke datasets die PHP en/of MySQL gebruiken, waaronder Facebook, Wikipedia, Yahoo!, Digg, Flickr, Google en YouTube.
  vrijdag 2 januari 2009 @ 13:15:03 #162
85919 Likkende_Lassie
Doe eens wat aan je ondertitel
pi_64575764
Bedankt voor jullie reacties.

Het zal in totaal misschien wel gaan om 500.000 producten, welke onderverdeelt zijn in categorien.

Zodra er een categorie is gekozen, is het mogelijk om een keuze te maken uit de begin letter.
Ik kan gewoon een functie maken die ik elke keer gebruik zodra er wijzigingen worden doorgevoerd in de database.

Cachen dus. Hoe zien jullie hier de tabel opbouw voor ?
Ik zelf dacht aan:

cat_ID, letter_ID.

Het is namelijk zo dat er per categorie een cache zal moeten zijn, van de beschikbare producten, en niet van de producten.

Anders wordt het natuurlijk wel weer als er gezocht gaat worden, en er ook een mogelijkheid moet zijn van het kiezen van een begin letter....
  vrijdag 2 januari 2009 @ 13:27:21 #163
85919 Likkende_Lassie
Doe eens wat aan je ondertitel
pi_64576105
Die array met het resultaat van DISTINCT(SUBSTRING(name, 1, 1)), daar heb ik de functie array_unique(); over laten gaan.

Ik kan ook eventueel deze array voor een aantal minuten laten cachen via memcached.
Als er geen array in memcached voor komt, dan kan ik hem laten genereren.... goed idee?
  vrijdag 2 januari 2009 @ 13:30:34 #164
75592 GlowMouse
l'état, c'est moi
pi_64576202
quote:
Op vrijdag 2 januari 2009 13:27 schreef Likkende_Lassie het volgende:
Die array met het resultaat van DISTINCT(SUBSTRING(name, 1, 1)), daar heb ik de functie array_unique(); over laten gaan.
Want de elementen zijn nog niet uniek vóór array_unique()?
quote:
Ik kan ook eventueel deze array voor een aantal minuten laten cachen via memcached.
Als er geen array in memcached voor komt, dan kan ik hem laten genereren.... goed idee?
Nee, zijn er alsnog mensen die lang op hun request wachten.
quote:
Op vrijdag 2 januari 2009 13:15 schreef Likkende_Lassie het volgende:
Cachen dus. Hoe zien jullie hier de tabel opbouw voor ?
Ik zelf dacht aan:

cat_ID, letter_ID.
Caches moet je niet te moeilijk over doen, serialized array in de categorieëntabel in een extra kolom is het makkelijkste.
eee7a201261dfdad9fdfe74277d27e68890cf0a220f41425870f2ca26e0521b0
  vrijdag 2 januari 2009 @ 17:12:45 #165
85919 Likkende_Lassie
Doe eens wat aan je ondertitel
pi_64583947
quote:
Op vrijdag 2 januari 2009 13:30 schreef GlowMouse het volgende:

[..]

Want de elementen zijn nog niet uniek vóór array_unique()?
[..]

Nee, zijn er alsnog mensen die lang op hun request wachten.
[..]

Caches moet je niet te moeilijk over doen, serialized array in de categorieëntabel in een extra kolom is het makkelijkste.
Toch wel, dacht het niet uniek terug te krijgen..

De cache is opgeslagen en werkt primá! bedankt!
  vrijdag 2 januari 2009 @ 17:19:15 #166
75592 GlowMouse
l'état, c'est moi
pi_64584251
quote:
Op vrijdag 2 januari 2009 17:12 schreef Likkende_Lassie het volgende:

[..]

Toch wel, dacht het niet uniek terug te krijgen..
Dat is opmerkelijk, waar denk je dat DISTINCT voor dient?
eee7a201261dfdad9fdfe74277d27e68890cf0a220f41425870f2ca26e0521b0
pi_64586555
quote:
Op vrijdag 2 januari 2009 13:07 schreef Tijn het volgende:

[..]

Er zijn genoeg grote websites met flinke datasets die PHP en/of MySQL gebruiken, waaronder Facebook, Wikipedia, Yahoo!, Digg, Flickr, Google en YouTube.
Dat weet ik Mijn vraag was dan ook meer of die sites eenzelfde pattern gebruiken voor het tonen van gegevens. Dus ook groeperen op eerste letter. Ik blijf er nog bij dat het niet handig is om alle records op te halen, in php te groeperen, en vervolgens een subset te laten zien. Om dat bij de volgende pageview weer helemaal te herhalen.
  vrijdag 2 januari 2009 @ 18:42:17 #168
85919 Likkende_Lassie
Doe eens wat aan je ondertitel
pi_64587158
quote:
Op vrijdag 2 januari 2009 17:19 schreef GlowMouse het volgende:

[..]

Dat is opmerkelijk, waar denk je dat DISTINCT voor dient?
Ja die doet hetzelfde, maar toen ik de code teste, en een print_r() deed, stonden er dubbele waardes in.
Later toen ik dit weer deed, was dit niet het geval. Of ik heb me vergist
pi_64599855
quote:
Op donderdag 1 januari 2009 23:44 schreef GlowMouse het volgende:

[..]

Het probleem is dat je dat lineair meer tijdrovende klusje op jouw manier bij elke request moet doen. Ten eerste moet de gebruiker langer wachten, ten tweede krijgt je server een probleem als je wat meer bezoekers krijgt.

Bij een request wil je gewoon snel de producten hebben die alleen met een bepaalde beginletter beginnen, eventueel ook alleen die op een bepaalde pagina voorkomen als je paginering gebruikt. Die andere producten wil je niet eerst in een arraytje stoppen, je wilt gewoon snel weten of ze bestaan. En als bij het groeien van je dataset de rekentijd lineair toeneemt, wil je gewoon dingen cachen als je op den duur ook daadwerkelijk veel producten krijgt, bijna onafhankelijk tegen welke prijs.
Voor hele grote datasets is dat misschien makkelijker, maar dan moet je echt huge datasets hebben. En 500k records vind ik daar niet onder vallen.
Ik denk (maar weet niet zeker) dat het queryen van een database om een simpele tabel op te halen langzamer is (gemeten uit php, niet rechtstreeks op je (my)sql) dan het bouwen van zon array. Maar nogmaals ik heb al tijden geen php gedaan. In .net weet ik zeker dat het sneller is gezien het daar (bijna) native draait.
Ik zal zo wel even een testje draaien om te timen.
  vrijdag 2 januari 2009 @ 23:44:56 #170
75592 GlowMouse
l'état, c'est moi
pi_64600198
quote:
Op vrijdag 2 januari 2009 23:37 schreef Database het volgende:

[..]

Voor hele grote datasets is dat misschien makkelijker, maar dan moet je echt huge datasets hebben. En 500k records vind ik daar niet onder vallen.
Ik denk (maar weet niet zeker) dat het queryen van een database om een simpele tabel op te halen langzamer is (gemeten uit php, niet rechtstreeks op je (my)sql) dan het bouwen van zon array. Maar nogmaals ik heb al tijden geen php gedaan. In .net weet ik zeker dat het sneller is gezien het daar (bijna) native draait.
Ik zal zo wel even een testje draaien om te timen.
Ik zal je helpen: op een vrij vlotte server die een tabel met 1 miljoen records geheel in zijn geheugen heeft staan duurt de SELECT DISTINCT-methode 2.7 seconden en de PHP-methode zonder twijfel langer (je hebt het dan aan megabytes aan data die je databaseserver bij elke request uit moet spugen).

Creëren van die array kost dus ook 2.7 seconden (want de tijd die je daarna in PHP nodig hebt is verwaarloosbaar) en hoeft eenmalig. Daarna kun je hem direct gebruiken bij elke request; zelfs als je hem met een aparte query op moet halen zal dat minder dan 1/100ste van een seconde kosten, als hij in het geheugen staat zelfs minder dan 1/1000ste.
eee7a201261dfdad9fdfe74277d27e68890cf0a220f41425870f2ca26e0521b0
pi_64601638
quote:
Op vrijdag 2 januari 2009 23:44 schreef GlowMouse het volgende:

[..]

Ik zal je helpen: op een vrij vlotte server die een tabel met 1 miljoen records geheel in zijn geheugen heeft staan duurt de SELECT DISTINCT-methode 2.7 seconden en de PHP-methode zonder twijfel langer (je hebt het dan aan megabytes aan data die je databaseserver bij elke request uit moet spugen).

Creëren van die array kost dus ook 2.7 seconden (want de tijd die je daarna in PHP nodig hebt is verwaarloosbaar) en hoeft eenmalig. Daarna kun je hem direct gebruiken bij elke request; zelfs als je hem met een aparte query op moet halen zal dat minder dan 1/100ste van een seconde kosten, als hij in het geheugen staat zelfs minder dan 1/1000ste.
Je hebt idd gelijk, het ophalen van 10000 records is de helft korter vergeleken met het doen van 10.000 assignments.

Lang leve .net Daar kan je 10.000 assignments nauwelijks timen
  zaterdag 3 januari 2009 @ 00:28:10 #172
75592 GlowMouse
l'état, c'est moi
pi_64601809
quote:
Op zaterdag 3 januari 2009 00:22 schreef Database het volgende:

[..]

Je hebt idd gelijk, het ophalen van 10000 records is de helft korter vergeleken met het doen van 10.000 assignments.
Welke 10.000 records haal je op, en welke assignments doe je? Arraytje steeds groter maken kost gewoon tijd, ook in .NET als je de grootte elke keer aan moet passen.
eee7a201261dfdad9fdfe74277d27e68890cf0a220f41425870f2ca26e0521b0
pi_64602685
quote:
Op zaterdag 3 januari 2009 00:28 schreef GlowMouse het volgende:

[..]

Welke 10.000 records haal je op, en welke assignments doe je? Arraytje steeds groter maken kost gewoon tijd, ook in .NET als je de grootte elke keer aan moet passen.
Query was:
$sql = "SELECT * FROM test WHERE id > 0"
Returned 10.000 2 kolom-rijen met een id en een md5 hash van de rij-id.

En mn forloop deed $a[$i] = $i.

Je hoeft de grootte neit elke keer aan te passen in dit geval gezien je een array van lists kan maken. Grootte van je array weet je (26). Grootte van list kan je benaderen met grootte van je resultset/26 (of je kan t iets nauwkeuriger doen). Dus daar komt ook weinig overhead bij kijken.
Als je t echt goed wil doen kan je je array op je stack alloceren ipv op je heap, dan heb je helemaal dikke performance.

Net bijna dezelfde forloop gedraaid in .net, daar kan ik in 2.0 seconden (minder dan 2.7 dus) 100 miljoen keer casten, een modulo doen en assignen.
1
2
for (int j = size - 1; j >= 0; j--)
  a[j] = (byte)(j % 255);

Je haalt in 2.0 seconden no way 100 miljoen records uit een database.

Ik denk dat in zo'n geval het maken van een dictionary vele malen voordelig is dan een query naar je database. Dat was eigenlijk ook mijn insteek in mijn eerste post, maar ja php performed gewoon crappy :9

Wat maakt t eigenlijk ook allemaal uit! Alsof het hier om high-performance systemen gaat :p
pi_64604608
quote:
Op vrijdag 2 januari 2009 00:12 schreef Light het volgende:

Het blijft wel PHP, dus aan het eind van het script is al je harde werk verloren gegaan.
Memcached anyone?
pi_64617916
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<?php ;
if (!empty($_POST)){ 
   switch ($_POST["soort"]){
      case "optellen":
         $getal3 = $_post["getal1"]+ $_post["getal2"];
         echo $_post["getal1"]."+".$_post["getal2"]." = ".$getal3;
         echo("<br> <a href =\"".$_SERVER["PHP_SELF"] . "\">Nieuwe berekening uitvoeren.</a>");
         break;
      case "aftrekken":
         $getal3 = $_post["getal1"]- $_post["getal2"];
         echo $_post["getal1"]."+".$_post["getal2"]." = ".$getal3;
         echo("<br> <a href =\"".$_SERVER["PHP_SELF"] . "\">Nieuwe berekening uitvoeren.</a>");
         break;
      case "delen":
         $getal3 = $_post["getal1"]+ $_post["getal2"];
         echo $_post["getal1"]."+".$_post["getal2"]." = ".$getal3;
         echo("<br> <a href =\"".$_SERVER["PHP_SELF"] . "\">Nieuwe berekening uitvoeren.</a>");
         break;
      case "vermenigvuldigen":
         $getal3 = $_post["getal1"]+ $_post["getal2"];
         echo $_post["getal1"]."+".$_post["getal2"]." = ".$getal3;
         echo("<br> <a href =\"".$_SERVER["PHP_SELF"] . "\">Nieuwe berekening uitvoeren.</a>");
         break;
      default:
         echo("Je hebt niks ingevuld!");
         echo("<br> <a href =\"".$_SERVER["PHP_SELF"] . "\">Nieuwe berekening uitvoeren.</a>");
         break;
   }
}else{
?>
<html>
<head>
   <title>Rekenmachientje 2e poging</title>
</head>
<body>
<FORM ACTION="<?php echo($_SERVER["PHP_SELF"]);?>" method="post">
Getal1 <input type="text" name="getal1"><br>
Getal2 <input type="text" name="getal2" ><br>
<INPUT TYPE="radio" NAME="soort" VALUE="optellen">Optellen(+)
<INPUT TYPE="radio" NAME="soort" VALUE="aftrekken">Aftrekken(-)
<INPUT TYPE="radio" NAME="soort" VALUE="delen">Delen(/)
<INPUT TYPE="radio" NAME="soort" VALUE="vermenigvuldigen">Vermenigvuldigen(*)
<BR>
<INPUT TYPE="submit" name ="Submit" VALUE="Verzenden">
<INPUT TYPE="reset" name="Reset" VALUE="Leegmaken">
</FORM>
<?php } ?>



hoe var dump ik dit?
Redacted
abonnement Unibet Coolblue Bitvavo
Forum Opties
Forumhop:
Hop naar:
(afkorting, bv 'KLB')