【问题标题】:Codeigniter Pagination: Run the Query Twice?Codeigniter 分页:运行两次查询?
【发布时间】:2011-02-14 08:12:55
【问题描述】:

我正在使用 codeigniter 和分页类。这是一个如此基本的问题,但我需要确保我没有遗漏任何东西。为了从 MySQL 数据库中获取分页结果所需的配置项,基本上需要运行两次查询,对吗?

换句话说,您必须先运行查询以确定总记录数,然后才能进行分页。所以我这样做:

执行此查询以获得结果数

$this->db->where('something', $something);
$query = $this->db->get('the_table_name');
$num_rows = $query->num_rows();

然后我必须再做一次才能得到带有限制和偏移的结果。比如:

$this->db->where('something', $something);
$this->db->limit($limit, $offset);
$query = $this->db->get('the_table_name');
if($query->num_rows()){

    foreach($query->result_array() as $row){

         ## get the results here
    }
}

我只是想知道我是否真的这样做了,因为查询总是需要运行两次?我使用的查询比上面显示的要复杂得多。

【问题讨论】:

    标签: codeigniter pagination


    【解决方案1】:

    不幸的是,为了进行分页,您必须知道将多少元素分解为页面。

    如果计算量太大,您总是可以缓存元素总数的结果。

    【讨论】:

      【解决方案2】:

      是的,您必须运行两个查询,但 $this->db->count_all('table_name'); 是一个更简洁的行。

      【讨论】:

      • 也比抓取整个记录集所需的开销要少得多
      【解决方案3】:

      分页需要读取一个记录集两次:

      1. 一次读取整个集合,以便统计总记录数
      2. 然后读取要显示的记录窗口

      这是我用于项目的示例。 “横幅”表有一个横幅列表,我想在分页屏幕上显示:

      • 使用公共类属性存储总记录 (public $total_records)
      • 使用私有函数构建查询(这对两个活动都很常见)。我们传递给此函数的参数 ($isCount) 减少了查询生成的数据量,因为对于行计数,我们只需要一个字段,但是当我们读取数据窗口时,我们需要所有必填字段。
      • get_list() 函数首先调用数据库查找总数并将其存储在 $total_records 中,然后读取一个数据窗口返回给调用者。
      • 请记住,如果不先调用 get_list() 方法,我们将无法访问 $total_records!

      class Banner_model extends CI_Model {
      
      public $total_records; //holds total records for get_list()
      
      public function get_list($count = 10, $start = 0) {
          $this->build_query();
          $query = $this->db->get();
          $result = $query->result();
          $this->total_records = count($result); //store the count
      
          $this->build_query();
          $this->db->limit($count, $start);
          $query = $this->db->get();
          $result = $query->result();
      
          return $result;
      }
      
      private function build_query($isCount = FALSE) {
          $this->db->select('*, b.id as banner_id, b.status as banner_status');
          if ($isCount) {
              $this->db->select('b.id');
          }
          $this->db->from('banner b');
          $this->db->join('company c', 'c.id = b.company_id');
          $this->db->order_by("b.id", "desc"); //latest ones first
      }
      

      现在从我们调用的控制器:

      $data['banner_list'] = $this->banner_model->get_list();
      $config['total_rows'] = $this->banner_model->total_records;
      

      当您开始使用 JOIN 时,事情会变得复杂,例如在我的示例中,您想要显示来自特定公司的横幅!您可以进一步阅读我关于此问题的博文:

      http://www.azmeer.info/pagination-hitting-the-database-twise/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-07-07
        • 1970-01-01
        • 2014-04-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多