【发布时间】:2011-02-17 02:31:26
【问题描述】:
我正在尝试让 Cakephp 分页利用 mysql 中的 SQL_CALC_FOUND_ROWS 功能在使用 LIMIT 时返回总行数。希望这样可以消除 paginateCount(),然后是 paginate() 的双重查询。
我已经把它放在了我的 app_model.php 中,它基本上可以工作,但还可以做得更好。有人可以帮我弄清楚如何覆盖 paginate/paginateCount 使其仅执行 1 个 SQL stmt?
/**
* 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
}
【问题讨论】:
-
我只想在这里补充一点,SQL_CALC_FOUND_ROWS 通常比使用直接 COUNT() 和 2 个查询慢得多。原因是Mysql如何寻找数据。尤其是在大型数据集上,SQL_CALC_FOUND_ROWS 解决方案可能需要数百万倍的时间(100 多秒与 0.004 秒跨越一百万条记录)。
标签: php mysql cakephp pagination