2012-06-09 2 views
5

Tôi đang đấu tranh với Doctrine 2 performce khi sử dụng HYDRATE_OBJECT. Khi tôi chuyển từ HYDRATE_ARRAY sang HYDRATE_OBJECT, thời gian sẽ mất gần 10 lần! Tôi đã sử dụng doctrine 2 and zend paginator như tài liệu tham khảo:Doctrine 2.2 + Zend Framework tối ưu hóa tốc độ phân trang

$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 

tôi nên xem gì ra cho? Làm cách nào để giảm thời gian xử lý và vẫn sử dụng HYDRATE_OBJECT? Có cách nào tốt hơn để thực hiện phân trang không?

* Sửa: Sử dụng ->setFirstResult($itemsPerPage * $page - $itemPerPage)->setMaxResults($itemsPerPage); giảm đáng kể thời gian tải, nhưng khi sử dụng $iterator:

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

Zend chỉ biết về $itemsPerPage, (count($iterator) == $itemsPerPage) và do đó các liên kết pagination luôn tính toán chỉ có 1 trang. Làm thế nào tôi có thể thực hiện một phân trang thích hợp bằng cách sử dụng Zend_Paginator, và chỉ tải $itemsPerPage thực thể?

+0

Bạn đã lược tả mã của mình chưa? Thật khó để trả lời câu hỏi này mà không biết bạn có loại logic kinh doanh nào trong các mô hình của mình. –

+0

Không có logic nghiệp vụ trong các thực thể ngoại trừ -> add() cho ArrayCollection. Phần còn lại là những người định cư đơn giản và getters. –

+0

Không được thiết lậpMaxResults một vấn đề khi sử dụng OneToMany tham gia? –

Trả lời

5

Tôi đã giải quyết vấn đề này ngay bây giờ bằng cách tạo trình bao bọc bộ chuyển đổi phân trang Zend cho phân trang Doctrine;

<?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()); 
    } 
} 
+0

Vấn đề thực tế bạn đã giải quyết là gì? –

+1

Thực hiện chậm khủng khiếp, bằng cách chỉ nạp $ itemsPerPageentities cho pagination –

+0

Không, ý tôi là cụ thể việc thực hiện tùy chỉnh 'Zend_Paginator' của bạn làm gì hiệu quả hơn là chỉ chuyển bộ sưu tập Doctrine đến' Zend_Paginate' –