fetchObject traag

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Jogai
  • Registratie: Juni 2004
  • Laatst online: 27-06 10:02
Onderstaande code is verschrikkelijk traag. Op internet kan ik niet vinden dat fetchObject traag is. Is er iets in mijn rows dat de boel vertraagd?
code:
1
2
3
4
5
6
7
while ($row = $stmt->fetchObject($dtoClassName))
{   
echo '<pre> PRE ' . time() . '</pre>';              
$arrResult[] = $row;
echo '<pre> PST ' . print_r($row, true) . '</pre>';
echo '<pre> PST ' . time() . '</pre>';
}

2 rijen uit de output:
PRE 1274893625

PST AnswerInfo Object
(
[Question] => Heeft u te maken met piekbelasting?
[Answer] => nooit
[QuestionTypeId] => sc
[ConstructId] => 6
[Construct] => Werkdruk
[Comment] => answerid=86&culture=nl-NL
)

PST 1274893625

PRE 1274893653

PST AnswerInfo Object
(
[Question] => Heeft u vrijheid bij het uitvoeren van uw werkzaamheden?
[Answer] => nooit
[QuestionTypeId] => sc
[ConstructId] => 11
[Construct] => Autonomie
[Comment] => answerid=41&culture=nl-NL
)

PST 1274893653

Klik hier om op linkedIn lid te worden van de Freelance Tweakers groep.


Acties:
  • 0 Henk 'm!

  • user109731
  • Registratie: Maart 2004
  • Niet online
Weet je zeker dat het aan fetchObject ligt? Wat gebeurt er als je fetch gebruikt ipv fetchObject:
PHP:
1
$row = $stmt->fetch(PDO::FETCH_ASSOC);

En wat doet de constructor van AnswerInfo?

[ Voor 3% gewijzigd door user109731 op 26-05-2010 19:21 ]


Acties:
  • 0 Henk 'm!

  • Feanathiel
  • Registratie: Juni 2007
  • Niet online

Feanathiel

Cup<Coffee>

In "de wereld van PHP" is het een vuistregel dat een object langzamer is dan een (assoc) array. Maar kijk uiteraard ook eens naar je query. Veel informatie staat er niet in de topicstart om direct een conclusie hieruit te halen.

Referentiemateriaal:
- http://www.jankoehoorn.nl...versen/mysql_performance/
- http://nl.php.net/manual/...ql-fetch-object.php#83632

Acties:
  • 0 Henk 'm!

  • Jogai
  • Registratie: Juni 2004
  • Laatst online: 27-06 10:02
Answerinfo is vrij simpel
En de query doet er maar 1 seconde over. Er komen dan bijna 500 rijen uit een sqlite(!) db.


code:
1
2
3
4
5
6
7
8
9
10
11
<?php
class AnswerInfo
{
    public $Question;
    public $Answer;
    public $QuestionTypeId;
    public $ConstructId;
    public $Construct;
    public $Comment;
}
?>

Klik hier om op linkedIn lid te worden van de Freelance Tweakers groep.


Acties:
  • 0 Henk 'm!

  • HuHu
  • Registratie: Maart 2005
  • Niet online
Wat is verschrikkelijk traag (1, 5, 10, 1000 seconden)? Waarom heb je een object, want zoals Feanathiel al zei is een assoc sneller. En waarom duurt je query een seconde, dat moet volgens mij veel sneller kunnen?

[ Voor 6% gewijzigd door HuHu op 26-05-2010 21:55 ]


Acties:
  • 0 Henk 'm!

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 28-06 17:12
Jogai schreef op woensdag 26 mei 2010 @ 19:41:
Er komen dan bijna 500 rijen uit een sqlite(!) db.
Als jij 500 rijen gaat weergeven verbaast het me absoluut niet dat het laden lang duurt. Zet eens onder en bovenaan je script een timestamp en gebruik output buffering om output pas na de stop timestamp weer te geven - zou me niet verbazen als de daadwerkelijke code snel zat is :)

[ Site ] [ twitch ] [ jijbuis ]


Acties:
  • 0 Henk 'm!

Anoniem: 308166

FragFrog schreef op woensdag 26 mei 2010 @ 22:23:
[...]

Als jij 500 rijen gaat weergeven verbaast het me absoluut niet dat het laden lang duurt. Zet eens onder en bovenaan je script een timestamp en gebruik output buffering om output pas na de stop timestamp weer te geven - zou me niet verbazen als de daadwerkelijke code snel zat is :)
500 rows zou geen probleem moeten zijn. Ik doe via AJAX in javascript ook stuk of 500 rijen cachen(dus in javascript staan die echt) en die weergeven zodra het nodig is(wat naar mijn idee precies hetzelfde is), dat kost wel beetje RAM, maar niet veel tijd.

Acties:
  • 0 Henk 'm!

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 28-06 17:12
Anoniem: 308166 schreef op donderdag 27 mei 2010 @ 00:59:
[...]

500 rows zou geen probleem moeten zijn. Ik doe via AJAX in javascript ook stuk of 500 rijen cachen(dus in javascript staan die echt) en die weergeven zodra het nodig is(wat naar mijn idee precies hetzelfde is), dat kost wel beetje RAM, maar niet veel tijd.
Hij geeft zo te zien tien regels weer per item - ergo, eerder 5000 regels tekst. In bepaalde browsers gaat dat in mijn ervaring nogal traag :)

Sowieso heb ik gemengde ervaringen hiermee - voor een bepaalde site laad ik een array van klanten in die bij bepaalde users ook makkelijk over de paar honderd regels gaat (nouja, 't is allemaal gecompact dus qua regels valt het mee, maar die hoeveelheid data) en dat levert geen problemen op - het is echt het weergeven van heel veel content wat de boel ophoudt. Then again, ik ben geen frontend developer, kan aan de specifieke implementatie gelegen hebben :+

[ Voor 30% gewijzigd door FragFrog op 27-05-2010 01:04 ]

[ Site ] [ twitch ] [ jijbuis ]


Acties:
  • 0 Henk 'm!

  • TheNephilim
  • Registratie: September 2005
  • Laatst online: 27-06 10:07

TheNephilim

Wtfuzzle

Mijn eerste ingeving is ook dat je beter fetchAssoc kan gebruiken...

Acties:
  • 0 Henk 'm!

  • bindsa
  • Registratie: Juli 2009
  • Niet online
Jogai schreef op woensdag 26 mei 2010 @ 19:41:
Answerinfo is vrij simpel
En de query doet er maar 1 seconde over. Er komen dan bijna 500 rijen uit een sqlite(!) db.


code:
1
2
3
4
5
6
7
8
9
10
11
<?php
class AnswerInfo
{
    public $Question;
    public $Answer;
    public $QuestionTypeId;
    public $ConstructId;
    public $Construct;
    public $Comment;
}
?>
Als ik eerlijk mag zijn vind ik 1s nogal traag. Mogen we je query een keer zien?

Acties:
  • 0 Henk 'm!

  • Jogai
  • Registratie: Juni 2004
  • Laatst online: 27-06 10:02
FragFrog schreef op woensdag 26 mei 2010 @ 22:23:
[...]

Als jij 500 rijen gaat weergeven verbaast het me absoluut niet dat het laden lang duurt. Zet eens onder en bovenaan je script een timestamp en gebruik output buffering om output pas na de stop timestamp weer te geven - zou me niet verbazen als de daadwerkelijke code snel zat is :)
De daadwerkelijke code is niet snel genoeg, want die gaat over de (60 seconden) timeout van php heen. De echo's staan er uiteraard alleen om te debuggen. Normaagesproken wordt alles in een string gezet die met fpdf in een pdf wordt geschreven.
L0calh0st schreef op donderdag 27 mei 2010 @ 09:40:
[...]


Als ik eerlijk mag zijn vind ik 1s nogal traag. Mogen we je query een keer zien?
Dat lijkt mij omdat het sqlite is.
SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
SELECT QuestionContent.Content AS Question,
  AnswerContent.Content        AS Answer,
  Question.QuestionTypeId,
  Question.ConstructId,
  ConstructContent.Title AS Construct,
  GivenAnswer.Comment
FROM GivenAnswer
INNER JOIN ConstructContent
ON ConstructContent.ConstructId = Question.ConstructId
AND ConstructContent.Culture    = ?
INNER JOIN Question
ON Question.QuestionId =GivenAnswer.QuestionId
INNER JOIN QuestionContent
ON QuestionContent.QuestionId =GivenAnswer.QuestionId
AND QuestionContent.Culture   = ConstructContent.Culture
INNER JOIN AnswerContent
ON AnswerContent.AnswerId = GivenAnswer.AnswerId
AND AnswerContent.Culture = ConstructContent.Culture
WHERE SurveyInvitationId  = ?
AND InvitationTicketId    = ?

de vraagtekens worden uiteraard vervangen door paramaters.

Klik hier om op linkedIn lid te worden van de Freelance Tweakers groep.


Acties:
  • 0 Henk 'm!

  • user109731
  • Registratie: Maart 2004
  • Niet online
Heb je nu al een andere fetch methode geprobeerd, zoals ik eerder voorstelde? Zo blijft het gissen waar het probleem zit :)

Is dat ook traag, probeer de query dan eens in de sqlite console of phpSQLiteAdmin (inclusief het printen van alle resultaten).

[ Voor 34% gewijzigd door user109731 op 27-05-2010 12:50 ]


Acties:
  • 0 Henk 'm!

  • Jogai
  • Registratie: Juni 2004
  • Laatst online: 27-06 10:02
PHP:
1
2
3
4
5
6
7
8
9
10
ob_start();
echo '<pre> PRE ' . time() . '</pre>';
$stmt->setFetchMode(PDO::FETCH_CLASS, $dtoClassName, array());
echo '<pre> PST ' . time() . '</pre>';
foreach($stmt as $row) {
    echo '<pre> ROW : ' . time() . ' <: ';  
    $arrResult[] = $row;
    echo print_r($row, true) . ' :> ' . time() . '</pre>';
}
ob_end_flush();


Nu loopt hij nog tegen de execution time limiet aan van 60 seconden. in knoda duurt het maar 1 seconde en dan staat alles op het scherm..

Ook dit werkt niet:
PHP:
1
2
3
4
ob_start();         
$arrResult = $stmt->fetchAll(PDO::FETCH_CLASS, $dtoClassName);
echo '<pre> PST ' . print_r($arrResult, true) . '</pre>';
ob_end_flush();


En nadat xdebug geinstalleerd is ziet de foutmeldinge er zo uit:

( ! )
Fatal error: Maximum execution time of 60 seconds exceeded in /applications/devel/Player2.0/classes/c4ob.DTOUtil/DTO.class.php
on line 51

Call Stack

#

Time

Memory

Function

Location

1

0.0018

247952

{main}( )

../answers.php:0

2

0.0411

4248336

AnswersModel->AnswersModel( )

../answers.php:24

3

0.0411

4248752

AnswersModel->LoadData( )

../AnswersModel.class.php:28

4

1.0573

4639352

DTOQueries:: getGivenAnswerInfoListBySurveyInvitationIdAndInvitationTicketIdAndCulture (
)

../AnswersModel.class.php:56

5

1.0573

4640200

DTO::getDTOListBySqlcopy(
)

../DTOQueries.class.php:466

6

1.0734

4682912

PDOStatement->fetchAll( )

../DTO.class.php:51

[ Voor 94% gewijzigd door Jogai op 27-05-2010 14:33 ]

Klik hier om op linkedIn lid te worden van de Freelance Tweakers groep.


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Jogai schreef op donderdag 27 mei 2010 @ 12:24:
Dat lijkt mij omdat het sqlite is.
..query..
Creeer maar wat indexen, want die query ziet er echt te simpel uit.

En haal je nu echt 500 rows op, of limiteer je dat stiekem pas bij de weergave? Gebruik eens een profiler om duidelijker te zien waar het aan ligt. En als je dan per se overal debug statements toe gaat voegen, gebruik dan microtime(true).

{signature}


Acties:
  • 0 Henk 'm!

  • Jory
  • Registratie: Mei 2006
  • Laatst online: 20:02
code:
1
2
3
PST 1274893625

PRE 1274893653

Als dit echt letterlijk de output van jou code is, duurt de fetchObject call bij jou dus 28 seconden.

Ik heb even een testje gedaan, waarin ik iets vergelijkbaars doe. Het database werk is wat eenvoudiger maar dat zou niet uit moeten maken (de execute() is immers niet wat veel tijd kost; je zegt zelf dat de query bij jou 1 seconde duurt), de PHP code doet ongeveer hetzelfde als jou testje. (Maar ik output wat minder en laat PHP voor me berekenen hoe lang het duurt enzo, maar dat maakt opzich allemaal niet zoveel uit.)

Bij mij duurt de eerste uitvoer meestal 3 microseconden, daarna wordt het minder. Als één simpele call bij jou dan 28 seconden duurt, is er ergens iets heel erg fout.
Heb je al gekeken of het niet aan de server ligt ofzo? (Lees, probeer het eens op een andere server.)

Mijn test code vind je op http://pastebin.com/PPWW0HKM
De resultaten zijn te vinden op http://pastebin.com/673JfVPH

Acties:
  • 0 Henk 'm!

  • Jogai
  • Registratie: Juni 2004
  • Laatst online: 27-06 10:02
Bedankt voor de moeite, ik heb je code even overgenomen:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
        $arrResult = array();
        $stmt = $pdo->prepare($sql);        
        if ($stmt->execute($arrParam))
        {   
            $before = microtime(true);
            while ($row = $stmt->fetchObject($dtoClassName))
            {       
                $after = microtime(true);           
                echo "Took " . ($after  - $before) . " microseconds.<br>".PHP_EOL;
                $before = microtime(true);
            }
            $after = microtime(true);
            echo "Took " . ($after - $before) . " microseconds.<br>".PHP_EOL;
        }

output:
code:
1
2
3
4
5
6
7
8
9
10
Took 6.8187713623E-5 microseconds.
Took 0.449250936508 microseconds.
Took 0.0348379611969 microseconds.
Took 0.034698009491 microseconds.
Took 0.0347120761871 microseconds.
Took 0.0348110198975 microseconds.
Took 0.0346801280975 microseconds.
Took 28.3327760696 microseconds.
Took 0.0350761413574 microseconds.
Took 0.0348918437958 microseconds.


Dus ja, 1 enkele call duurt 28 seconden. Ik neem aan dat het niet in fetchObject zit, want de halve php wereld zal die wel gebruiken, en ik zie nergens performance issues op internet beschreven. Verder zoeken dan maar...

Klik hier om op linkedIn lid te worden van de Freelance Tweakers groep.

Pagina: 1