2

実行速度が遅すぎるクエリがあります。ページの読み込みには数分かかります。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;
4

3 に答える 3

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;

上記の改訂されたコードをご覧ください!

于 2010-02-10T13:40:40.197 に答える
2

あなたのコードでは、あなたは:

  • まず、条件に一致するすべてのレコードを選択してフェッチします
    • select......fromそしてそのすべてを参照してください
    • fetchAll直後の回線での呼び出し
  • そして、あなたはパギネーターを使用しているだけです、
    • fetchAll呼び出しによって返された結果について。

そうすれば、そうです、100,000レコードすべてがDBからフェッチされ、PHPによって操作され、渡されZend_Paginatorて、それらと連携する必要があります...ほとんどすべてを破棄するだけです。


を使用Zend_Paginatorすると、のインスタンスを渡してZend_Db_Select、必要なを指定してクエリを実行できるようになりますlimit

たぶん、DbSelectとDbTableSelectアダプターに関する例は、これをどのように達成できるかを理解するのに役立つかもしれません(申し訳ありませんが、実際の例はありません)

于 2010-02-10T11:56:01.593 に答える
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;
于 2010-02-17T12:28:03.470 に答える