zend框架paginator(Zend_Paginator)结果太慢了

时间:2010-02-10 11:49:39

标签: php zend-framework zend-paginator

我的查询运行速度太慢。该页面需要几分钟才能加载。 我正在表上加入超过100,000条记录的表。在我的查询中,它是抓取所有记录还是仅获得我需要的页面数量?我是否需要在查询中设置限制?如果我这样做,那不会给分页器带来错误的记录数吗?

$paymentsTable = new Donations_Model_Payments();
$select = $paymentsTable->select(Zend_Db_Table::SELECT_WITH_FROM_PART);
$select->setIntegrityCheck(false)
    ->from(array('p' => 'tbl_payments'), array('clientid', 'contactid', 'amount'))
    ->where('p.clientid = ?', $_SESSION['clientinfo']['id'])
    ->where('p.dt_added BETWEEN  \''.$this->datesArr['dateStartUnix'].'\' AND \''.$this->datesArr['dateEndUnix'].'\'')
        ->join(array('c' => 'contacts'), 'c.id = p.contactid', array('fname', 'mname', 'lname'))
        ->group('p.id')
        ->order($sortby.' '.$dir)
        ;
        $payments=$paymentsTable->fetchAll($select);

// paginator
$paginator = Zend_Paginator::factory($payments);
$paginator->setCurrentPageNumber($this->_getParam('page'), 1);
$paginator->setItemCountPerPage('100'); // items pre page
$this->view->paginator = $paginator;

$payments=$payments->toArray();
$this->view->payments=$payments;

3 个答案:

答案 0 :(得分:3)

请参阅下面的修订代码。您需要通过正确的适配器将$select传递给Zend_Paginator。否则你将看不到性能优势。

$paymentsTable = new Donations_Model_Payments();
$select = $paymentsTable->select(Zend_Db_Table::SELECT_WITH_FROM_PART);
$select->setIntegrityCheck(false)
    ->joinLeft('contacts', 'tbl_payments.contactid = contacts.id')
    ->where('tbl_payments.clientid = 39')
    ->where(new Zend_Db_Expr('tbl_payments.dt_added BETWEEN "1262500129" AND "1265579129"'))
    ->group('tbl_payments.id')
    ->order('tbl_payments.dt_added DESC');

// paginator
$paginator = new Zend_Paginator(new Zend_Paginator_Adapter_DbTableSelect($select));
$paginator->setCurrentPageNumber($this->_getParam('page', 1));
$paginator->setItemCountPerPage('100'); // items pre page
$this->view->paginator = $paginator;

请参阅上面的修订代码!

答案 1 :(得分:2)

在您的代码中,您是:

  • 首先,选择并获取符合您条件的所有记录
    • 请参阅select ... from ...以及所有
    • 以及
    • 后面一行中对fetchAll的调用
  • 并且,只有,您正在使用分页器,
    • 关于fetchAll来电返回的结果。

有了这个,我会说,是的,你的所有100,000条记录都是从数据库中提取的,由PHP操纵,传递给Zend_Paginator,它必须与它们一起工作...只是为了丢弃几乎所有的它们。


使用Zend_Paginator,您应该能够将Zend_Db_Select的实例传递给它,并让它执行查询,指定所需的limit

也许有关DbSelect and DbTableSelect adapter的示例可能会帮助您了解如何实现这一目标(抱歉,我没有任何有效的例子)

答案 2 :(得分:1)

我个人通过COUNT(*)计算结果并将其传递给zend_paginator。我永远不明白你为什么要将zend_paginator直接链接到数据库结果中。我可以看到优点和缺点,但实际上,它是远远不够的。

请记住,你只需要100个结果,你需要获得100'000 +然后zend_paginator将它们扔掉。实际上你想要计算一下。

    $items      = Eurocreme_Model::load_by_type(array('type' => 'list', 'from' => $from, 'to' => MODEL_PER_PAGE, 'order' => 'd.id ASC'));
    $count      = Eurocreme_Model::load_by_type(array('type' => 'list', 'from' => 0, 'to' => COUNT_HIGH, 'count' => 1));

    $paginator = Zend_Paginator::factory($count);
    $paginator->setItemCountPerPage(MODEL_PER_PAGE);
    $paginator->setCurrentPageNumber($page);

    $this->view->paginator = $paginator;
    $this->view->items = $items;