5

I'm struggling with Doctrine 2 performce when using HYDRATE_OBJECT. When I switch from HYDRATE_ARRAY to HYDRATE_OBJECT, it takes nearly 10 times longer! I've used doctrine 2 and zend paginator as reference:

$query = $em->createQuery($dql)
    ->setHydrationMode(\Doctrine\ORM\AbstractQuery::HYDRATE_ARRAY)
    ->setParameter('x', 1);

// Pagination
$paginator = new Doctrine\ORM\Tools\Pagination\Paginator($query, false);
$iterator = $paginator->getIterator();
die(); // 160 ms

vs

$query = $em->createQuery($dql)
    ->setHydrationMode(\Doctrine\ORM\AbstractQuery::HYDRATE_OBJECT)
    ->setParameter('x', 1);

// Pagination
$paginator = new Doctrine\ORM\Tools\Pagination\Paginator($query, false);
$iterator = $paginator->getIterator();
die(); // 1.4s

What should I watch out for? How to reduce the processing time and still utilize HYDRATE_OBJECT? Is there a better way to accomplish pagination?

*Edit: Using ->setFirstResult($itemsPerPage * $page - $itemPerPage)->setMaxResults($itemsPerPage); significantly decrease loading time, but when using $iterator:

$adapter =  new \Zend_Paginator_Adapter_Iterator($iterator);
$zend_paginator = new \Zend_Paginator($adapter);          
$zend_paginator->setItemCountPerPage($itemsPerPage)
    ->setCurrentPageNumber($page);

Zend only knows about $itemsPerPage, (count($iterator) == $itemsPerPage) and thus the pagination links always calculate 1 page only. How can I accomplish a proper pagination using Zend_Paginator, and only load $itemsPerPageentities?

Community
  • 1
  • 1
Jon Skarpeteig
  • 4,118
  • 7
  • 34
  • 53

1 Answers1

5

I solved this now by creating a Zend pagination adapter wrapper for Doctrine pagination;

<?php
class PaginatorAdapter extends Doctrine\ORM\Tools\Pagination\Paginator implements
        Zend_Paginator_Adapter_Interface
{
    public function getItems($offset, $itemCountPerPage)
    {
        $this->getQuery()->setFirstResult($offset)->setMaxResults($itemCountPerPage);
        return $this->getQuery()->getResult($this->getQuery()->getHydrationMode());
    }
}
Jon Skarpeteig
  • 4,118
  • 7
  • 34
  • 53
  • 1
    Horribly slow execution, by only loading $itemsPerPageentities for pagination – Jon Skarpeteig Jun 10 '12 at 07:35
  • No, I mean specifically what did your custom implementation of `Zend_Paginator` do more efficiently than just passing the Doctrine collection to `Zend_Paginate` – Mike B Jun 10 '12 at 07:57
  • 1
    The getIterator() seems to populate every single entry (E.G 10000 rows). Alternatively the setMaxResults would make iterator count(), always return the maxresult integer (not the entire collection) – Jon Skarpeteig Jun 10 '12 at 20:30
  • @JonSkarpeteig: How do you use that? Do you use getItems instead of using the adapter as an iterateable object? Dos this work with OneToMayn Joins as well? – Andresch Serj Jun 13 '12 at 09:42
  • I use it as a regular Zend Paginator in my view scripts. For more information you can have a look at: http://framework.zend.com/manual/en/zend.paginator.usage.html – Jon Skarpeteig Jun 14 '12 at 08:46