memory limit met AJAX request

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Medina Wal

Medina Wal

05/07/2014 15:31:57
Quote Anchor link
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?
 
PHP hulp

PHP hulp

05/05/2024 15:38:00
 
- Ariën  -
Beheerder

- Ariën -

05/07/2014 16:00:40
Quote Anchor link
Ergens zal je script zeer inefficiënt bezig zijn, en dus zul je toch moeten achterhalen hoe en wat en de boel (deels) herschrijven.
Gewijzigd op 05/07/2014 16:06:24 door - Ariën -
 
Medina Wal

Medina Wal

05/07/2014 16:29:16
Quote Anchor link
Ik begrijp niet zo goed wat er inefficient is aan deze code:
(maar ik ben dan ook niet zo ervaren)

Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
$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++;
}
 
Frank Nietbelangrijk

Frank Nietbelangrijk

05/07/2014 18:20:34
Quote Anchor link
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:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<?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>";
?>
Gewijzigd op 05/07/2014 18:21:50 door Frank Nietbelangrijk
 
Medina Wal

Medina Wal

05/07/2014 21:03:01
Quote Anchor link
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?
 
Pipo Clown

Pipo Clown

05/07/2014 21:52:34
Quote Anchor link
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.
 
Local Dev

Local Dev

05/07/2014 22:27:43
Quote Anchor link
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??
Gewijzigd op 05/07/2014 22:28:02 door Local Dev
 
Frank Nietbelangrijk

Frank Nietbelangrijk

06/07/2014 02:19:40
Quote Anchor link
memcache zou niet nodig moeten zijn om een paar menu-tjes op het scherm te toveren. Wie is je provider?
 
Medina Wal

Medina Wal

06/07/2014 11:26:18
Quote Anchor link
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
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
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
 
Frank Nietbelangrijk

Frank Nietbelangrijk

06/07/2014 11:55:56
Quote Anchor link
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?
 
Obelix Idefix

Obelix Idefix

06/07/2014 12:17:11
Quote Anchor link
Je zou Antagonist ook kunnen vragen of ze iets kunnen vinden.
Doorgaans is hun klantenservice behulpzaam.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
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));
            }
        });
});

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
 
Medina Wal

Medina Wal

06/07/2014 12:18:35
Quote Anchor link
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
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();


regel 11 is de bind result regel
hier komt één woord uit
Gewijzigd op 06/07/2014 12:20:26 door Medina Wal
 
Frank Nietbelangrijk

Frank Nietbelangrijk

06/07/2014 12:22:48
Quote Anchor link
en waar komt $omschrijving vandaan?

Laat eens wat meer code zien
 
Medina Wal

Medina Wal

06/07/2014 12:24:53
Quote Anchor link
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.

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
 
Frank Nietbelangrijk

Frank Nietbelangrijk

06/07/2014 13:06:54
Quote Anchor link
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.
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.