Hallo,

Ik heb een restaurant site waar ik via een ajax request een menukaart uit de database haal.
Thuis geen enkel probleem (iis), maar bij mijn webhosting provider (linux) kreeg ik direct aan foutmelding aangaande de memory limit.
Na even zoeken vond ik de manier om het aan te passen, echter ik heb nu een limiet nodig van 4128M, wat wel wat veel is met als logisch gevolg dat het de site enorm vertraagd.
Hoe kan ik dit verhelpen, of is de enige oplossing het php script serieus te gaan herschrijven?
Ergens zal je script zeer inefficiënt bezig zijn, en dus zul je toch moeten achterhalen hoe en wat en de boel (deels) herschrijven.
Ik begrijp niet zo goed wat er inefficient is aan deze code:
(maar ik ben dan ook niet zo ervaren)

$sql = "SELECT Volgorde
		FROM menuitem
		ORDER BY Volgorde DESC
		LIMIT 1";
$resultcounter = $mysqli->query($sql);
while($row = $resultcounter->fetch_assoc()) {
	$counter	= $row['Volgorde'];
}
echo "";	
$i = 1;
while ($i <= $counter) {
$sql = "SELECT Menuonderdeel, Volgorde
		From menuitem
		Where Volgorde = $i ";
$resultMenu = $mysqli->query($sql);	
while($row = $resultMenu->fetch_assoc()) {		
	$menuonderdeel = "<table class='menukaart hide' id='".$row['Menuonderdeel']."'><tr><th colspan='2'><h3>".$row['Menuonderdeel']."</h3><hr></th></tr>";
	echo $menuonderdeel;
		
	 
	$sql = "SELECT * 
		FROM gerechten 
		inner join menuitem 
		on gerechten.MenuID=menuitem.MenuID 
		where Volgorde= $i";
	$result = $mysqli->query($sql);
while($row = $result->fetch_assoc()) {			
		$menukaart	= "<tr><td><h4>".$row['Naam']."</h4><p>"
		.$menukaart	= $row['Omschrijving']."</td>";
		$prijs	= "<td><span class='prijs'>&euro; ".number_format($row['Prijs'], 2, ',', ' ')."</span></p><br>";
		echo $menukaart.$prijs."</td></tr>";
}
echo "</table>";
}

$i++;
} 
Ik begrijp wel dat deze code niet efficiënt is. De queries bieden je veelal de mogelijkheid om in één keer alles uit de database te trekken dat je nodig hebt. Jij doet echter een query in een dubbele while lus. als beiden lussen 10 keer uitgevoerd worden dan ga je 10x10 = 100 queries afvuren. Dat is niet de bedoeling.
De bedoeling is één keer een query (het liefst) en dan alle records doorlopen.

Volgens mij zou je aan dit genoeg hebben:
<?php

$sql = "
SELECT
Menuonderdeel, Volgorde, Naam, Omschrijving, Prijs
FROM
gerechten
INNER JOIN
menuitem
ON
gerechten.MenuID = menuitem.MenuID
ORDER BY
Menuonderdeel, Volgorde DESC
";

$result = $mysqli->query($sql);

$menuOnderdeel = '?';
$insideTable = false;
while($row = $result->fetch_assoc())
{
// een ander menu onderdeel ?
if($menuOnderdeel != $row['Menuonderdeel'])
{
// indien nodig sluit de vorige html table af.
if($insideTable)
echo "</table>";

echo "<table class='menukaart hide' id='".$row['Menuonderdeel']."'><tr><th colspan='2'><h3>".$row['Menuonderdeel']."</h3><hr></th></tr>";

$insideTable = true;
$menuOnderdeel = $row['Menuonderdeel'];
}

$menukaart = "<tr><td><h4>".$row['Naam']."</h4><p>"
.$menukaart = $row['Omschrijving']."</td>";
$prijs = "<td><span class='prijs'>&euro; ".number_format($row['Prijs'], 2, ',', ' ')."</span></p><br>";
echo $menukaart.$prijs."</td></tr>";
}

// indien nodig sluit de laatste html table af.
if($insideTable)
echo "</table>";
?>
Dank je voor je reactie,
ik ben idd nog niet zo bedreven in het efficiënt aanspreken van de database en dit ziet er veel beter uit, waarvoor mijn grote dank.
Echter krijg ik nog steeds deze melding:
Fatal error: Allowed memory size of 100663296 bytes exhausted (tried to allocate 4294967296 bytes
en het lijkt mij erg veel(? of zie ik dat fout en is dit wel redelijk normaal?).
Het duurt iig te lang. (zie http://www.test.dagianfranco.nl/#Menukaart)
Hoe kan ik dit verhelpen?
Ik krijg het menu in een fractie van een seconde voorgeschoteld.

Ik vraag mij wel af waarom jij het dan niet te zien krijgt want het lijkt mij een foutmelding van de server.
Duurt te lang, ik zou gebruik gaan maken van memcache, evt in samenwerking met varnish.

Ik hoop trouwens dat je ook rekening houdt met het feit dat alle zoekmachines tot op heden de data niet kunnen lezen op deze manier, en dat je gebruik moet maken van prerenderer om ook de site zoekmachine vriendelijk te houden??
memcache zou niet nodig moeten zijn om een paar menu-tjes op het scherm te toveren. Wie is je provider?
Pipo Clown op 05/07/2014 21:52:34

Ik krijg het menu in een fractie van een seconde voorgeschoteld.

Ik vraag mij wel af waarom jij het dan niet te zien krijgt want het lijkt mij een foutmelding van de server.


Door dit in mijn code te plaatsen
ini_set('memory_limit','4128M');
krijg ik geen foutmelding, echter deze memory limit zorgt er voor dat de pagina http://www.test.dagianfranco.nl/#Menukaart ruim 4 seconden nodig heeft om te laden. Ter illustratie heb ik de memory limit er nu even uitgegooid.


Local Dev op 05/07/2014 22:27:43

Duurt te lang, ik zou gebruik gaan maken van memcache, evt in samenwerking met varnish.

Dit kende ik nog niet, daar ga ik me eens even in verdiepen, grote dank hiervoor.

Frank Nietbelangrijk op 06/07/2014 02:19:40
Wie is je provider?

Antagonist
Het zal debuggen worden.

wat gebeurt er als er een limit van bijvoorbeeld 10 aan de query meegegeven wordt.
Ligt het wel aan de query?
wat staat er op regel 11 van test/Menukaart/index.php?

Je zou Antagonist ook kunnen vragen of ze iets kunnen vinden.
Doorgaans is hun klantenservice behulpzaam.


$(document).ready(function() {
    var easterEgg = "beheer";
    var eggLength = easterEgg.length;
    var keyHistory = '';
    var match;
	
        $(document).keypress(function(e) {
            keyHistory += String.fromCharCode(event.which)
            match = keyHistory.match(easterEgg); 
            if(match) {
                window.open("Admin/index.php");
                keyHistory = match =  '';
            } else if (keyHistory.length > 30) {
                keyHistory = keyHistory.substr((keyHistory.length - eggLength - 1));
            }
        });
});

Is dat een handige/verstandige manier?
Zo maak je het pad naar je admin wel heel eenvoudig.

Reageren