创建一个有效的分页系统

时间:2011-06-07 07:46:53

标签: php sql pagination

所以我正在为类似博客的系统创建一个分页系统。我已经有了使用limit,offset限制查询的整个概念。但是,我在创建实际导航时遇到了问题。

我不知道如何计算我总共的页数。现在,显然我可以运行一个简单地选择所有行的计数的查询,但是,我觉得这不是最有效的方法。

无论如何,我可以在原始查询中拉到总行数吗?

 $this->DB->build(  array('select'   => 'a.*', 
                     'from'     => array( 'ccs_custom_database_1' => 'a' ),
                      'order' => 'field_3 DESC',
                      'where' => 'field_6=",1,"',
                      'limit' => array($page,10),

                     'add_join'  => array(
                    array(
                        'select'    => 'm.members_display_name,m.members_seo_name',
                        'from'      => array( 'members' => 'm' ),
                        'type'      => 'inner',
                        'where'     => 'a.member_id=m.member_id'


                    ), 
                    array(
                        'select'    => 'c.category_name,c.category_furl_name',
                        'from'      => array( 'ccs_database_categories' => 'c' ),
                        'type'      => 'inner',
                        'where'     => 'a.category_id=c.category_id'            
                    )),

                    ));

4 个答案:

答案 0 :(得分:6)

如果您的表使用MyISAM引擎,则运行COUNT(*)是一个O(1)操作,因为它保留了总行数的缓存值。

即使你没有使用它,或者查询略有不同,我怀疑做一个COUNT会成为系统的瓶颈。

如果它真的是一个很大的问题(我建议在一个表上测试一些你预期会先假的假数据),一个选择是采取一种更实用的方法来它。在您的用例中,您的用户可能会有所不同,但是,接受无论如何都没有人真正使用分页。最多,你可以期望有人在放弃之前经历2或3页。使用过滤和排序将用户想要的数据推送到第一页。

但是,即使使用过滤和排序,您仍然需要显示一些类别的分页,因此您可以采用这种方法:给定15个记录的页面大小,选择第一个151 (每页15个* 10页+ 1个)记录并计算您获得的数量。如果数字小于该数字,则显示“第1页,共8页”或其他内容。如果数字是151,那么你有超过10页,所以显示“第1页”。这是我在一张桌子上使用的一种方法,它有大约1200万条记录,而且效果非常好。

答案 1 :(得分:4)

您有2个选项。

  1. 使用查询选择总计数。
  2. 使用FOUND_ROWS()
  3. 我更喜欢第二种选择,但就性能而言,它很重要。

答案 2 :(得分:2)

您始终可以对数据进行非规范化。例如,Post表可以包含CommentsCount列,该列会在添加和删除注释时更新。

然而,在大多数情况下,这将是一个微观优化,因为每个帖子很少会有大量的评论。

答案 3 :(得分:0)

请使用PEAR's Pager课程。它会自动处理几乎所有内容,您可以使用$pager->getCurrentPageID()perPage属性来获取LIMIT子句。

不重新发明轮子可以节省编码,发现错误和修复错误。