Home > Back-end >  How to avoid large amounts of queries when fetching doctrine relational entities
How to avoid large amounts of queries when fetching doctrine relational entities

Time:09-01

I never paid much attention to the number of queries generated by doctrine, until today when I got a fairly simple task (or so I thought) running 750 queries for 16 seconds...

public function indexAction()
{
    $em = $this->em;

    $risks = $em->getRepository('App\Entity\Hazardlog\Risk')->findAll();

    //filter out only risks belonging to a current version analysis
    $risksCurrent = array();

    foreach($risks as $r) {
        if ($r->getAnalysis()->getCurrentVersion() == true) {
            $risksCurrent[] = $r;
        }               
    }

    return $this->render('risk/index.html.twig', array(
        'risks' => $risksCurrent,
    ));
}

So I suppose for each turn in the loop a new SQL query is executed. I thought the objects were fetched in their entirety upon first call, and then it didn't "cost" me a DB call to access properties on those objects, but sorely mistaken I was =)

Is there a way to do this more efficiently without resorting to writing good old SQL queries? I can do it by

SELECT * FROM risk JOIN analysis ON risk.analysis = analysis.id WHERE (analysis.CurrentVersion = true)

But I would rather deal with the entity objects than SQL...


Changing the controller to...

public function indexAction()
{
    $em = $this->em;

    $query = $em->createQuery('SELECT * FROM risk JOIN analysis ON risk.analysis = analysis.id WHERE (analysis.CurrentVersion = true)');
    $risksCurrent = $query->getResult();

    return $this->render('risk/index.html.twig', array(
        'risks' => $risksCurrent,
    ));
}

... got it down to 18 queries in half a second which is a lot more comfortable... still I only see one single query there in my code so I don't know what's going on with that

  • Related