2010-05-08 104 views
3

我想讓CakePHP頁面利用mysql中的SQL_CALC_FOUND_ROWS功能來返回使用LIMIT時總行數。希望這可以消除paginateCount()和paginate()的雙重查詢。cakephp分頁使用mysql SQL_CALC_FOUND_ROWS

我已經把這個在我app_model.php,它基本上工作,但它可以做的更好。有人能幫我弄清楚如何重寫paginate/paginateCount,因此它只執行1個SQL語句嗎?

/** 
* Overridden paginateCount method, to using SQL_CALC_FOUND_ROWS 
*/ 
public function paginateCount($conditions = null, $recursive = 0, $extra = array()) { 
    $options = array_merge(compact('conditions', 'recursive'), $extra); 
    $options['fields'] = "SQL_CALC_FOUND_ROWS `{$this->alias}`.*"; 

問:如何獲得paginate()中使用的SAME限制值?

$options['limit'] = 1; // ideally, should return same rows as in paginate()  

問:我們可以以某種方式直接將查詢結果分頁,而不需要額外的查詢嗎?

$cache_results_from_paginateCount = $this->find('all', $options); 
    /* 
    * note: we must run the query to get the count, but it will be cached for multiple paginates, so add comment to query 
    */ 
    $found_rows = $this->query("/* do not cache for {$this->alias} */ SELECT FOUND_ROWS();"); 
    $count = array_shift($found_rows[0][0]); 
    return $count; 
} 

/** 
* Overridden paginate method 
*/ 
public function paginate($conditions, $fields, $order, $limit, $page = 1, $recursive = null, $extra = array()) { 
    $options = array_merge(compact('conditions', 'fields', 'order', 'limit', 'page', 'recursive'), $extra); 

問:我們可以以某種方式直接從paginateCount()獲得$ cache_results_for_paginate嗎?

return $cache_results_from_paginateCount; // paginate in only 1 SQL stmt 
    return $this->find('all', $options); // ideally, we could skip this call entirely 
} 
+0

我只是想在這裏補充一點,SQL_CALC_FOUND_ROWS往往比使用COUNT()和2個查詢慢得多。這是Mysql尋找數據的原因。特別是在大型數據集中,SQL_CALC_FOUND_ROWS解決方案可以花費數百萬次(100多萬秒,而在100萬條記錄中爲0.004秒)。 – Oddman 2013-11-22 14:03:19

回答

0

我解決這個從中返回當前頁面,結果在相同的反應可用總數的結果Web服務分頁結果的方式是將PAGINATE財產從控制器複製到模型在您的控制器操作中,在調用$ this-> paginate();之前,以便我的分頁設置在模型的paginateCount()方法中可用。然後在paginateCount()中調用web服務來獲得結果。然後將結果存儲在模型的屬性中,然後返回可用結果的總數。然後在模型的paginate()方法中,我返回我提取並存儲在paginateCount()方法中的結果。

也許沿着這些路線的東西也可能適合你?

+0

我使用了一個類的靜態var來緩存paginateResponse,但是我從來沒有想過我也可以通過相同的機制傳遞paginate選項。 只要我可以設置recursive = -1,但似乎工作正常,但如果在分頁中存在關聯,那麼「SELECT FOUND ROWS」在關聯查詢後被調用,並返回錯誤的結果。 – michael 2010-05-11 12:53:39

+0

也很難在find()中獲得正確的$ fields值。目前正在使用 $ fields = is_array($ fields) ? array_unshift($ fields,'SQL_CALC_FOUND_ROWS') :!empty($ fields)? array('SQL_CALC_FOUND_ROWS',$ fields) :「SQL_CALC_FOUND_ROWS'{$ this-> alias}'。*」; 但實際上只測試了$ fields = ;; – michael 2010-05-11 13:10:22