memory limit met AJAX request
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?
Gewijzigd op 05/07/2014 16:06:24 door - Ariën -
(maar ik ben dan ook niet zo ervaren)
Code (php)
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
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
$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'>€ ".number_format($row['Prijs'], 2, ',', ' ')."</span></p><br>";
echo $menukaart.$prijs."</td></tr>";
}
echo "</table>";
}
$i++;
}
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'>€ ".number_format($row['Prijs'], 2, ',', ' ')."</span></p><br>";
echo $menukaart.$prijs."</td></tr>";
}
echo "</table>";
}
$i++;
}
De bedoeling is één keer een query (het liefst) en dan alle records doorlopen.
Volgens mij zou je aan dit genoeg hebben:
Code (php)
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
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
<?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'>€ ".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>";
?>
$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'>€ ".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>";
?>
Gewijzigd op 05/07/2014 18:21:50 door Frank Nietbelangrijk
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 vraag mij wel af waarom jij het dan niet te zien krijgt want het lijkt mij een foutmelding van de server.
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??
Gewijzigd op 05/07/2014 22:28:02 door Local Dev
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.
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 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
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?
Doorgaans is hun klantenservice behulpzaam.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$(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));
}
});
});
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.
Gewijzigd op 06/07/2014 12:23:34 door Obelix Idefix
Code (php)
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
$sql = "SELECT Omschrijving
FROM gerechten
WHERE GerechtID='1'";
$stmt = $mysqli->prepare($sql);
$stmt->bind_result($Omschrijving);
$stmt->execute();
$stmt->fetch();
$stmt->close();
FROM gerechten
WHERE GerechtID='1'";
$stmt = $mysqli->prepare($sql);
$stmt->bind_result($Omschrijving);
$stmt->execute();
$stmt->fetch();
$stmt->close();
regel 11 is de bind result regel
hier komt één woord uit
Gewijzigd op 06/07/2014 12:20:26 door Medina Wal
Laat eens wat meer code zien
Obelix en Idefix op 06/07/2014 12:17:11:
Je zou Antagonist ook kunnen vragen of ze iets kunnen vinden.
Doorgaans is hun klantenservice behulpzaam.
Doorgaans is hun klantenservice behulpzaam.
Je hebt helemaal gelijk, echter heb ik vooralsnog sterk de indruk dat het aan mijn programmeer kunst gebrek ligt, vandaar dat ik hier terecht ben gekomen
Toevoeging op 06/07/2014 12:58:09:
jeetje, je zette me wel op het goede spoor, Frank. Na even te zoeken op 'on bind result allowed memory exhausted' vond ik iemand met hetzelfde probleem.
Na wat gelezen, en doorgeklikt te hebben, blijkt dat het 'gewoon' aan mijn db instelling te liggen, ipv 'longtext' te kiezen als column type, moest ik 'text' kiezen (eigenlijk ook wel logisch).
Het bleek dus een db probleem te zijn...
Wel heel hartelijk dank voor de hulp.
Gewijzigd op 06/07/2014 13:12:08 door Medina Wal
Super en goed gevonden van je. Ja longtexten, blob's zijn geheugenvreters. Die zou je nooit in een lange lijst moeten opvragen maar enkel één tegelijk.