所以我正在为类似博客的系统创建一个分页系统。我已经有了使用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'
)),
));
答案 0 :(得分:6)
如果您的表使用MyISAM引擎,则运行COUNT(*)
是一个O(1)操作,因为它保留了总行数的缓存值。
即使你没有使用它,或者查询略有不同,我怀疑做一个COUNT
会成为系统的瓶颈。
如果它真的是一个很大的问题(我建议在一个表上测试一些你预期会先假的假数据),一个选择是采取一种更实用的方法来它。在您的用例中,您的用户可能会有所不同,但是,接受无论如何都没有人真正使用分页。最多,你可以期望有人在放弃之前经历2或3页。使用过滤和排序将用户想要的数据推送到第一页。
但是,即使使用过滤和排序,您仍然需要显示一些类别的分页,因此您可以采用这种方法:给定15个记录的页面大小,选择第一个151 (每页15个* 10页+ 1个)记录并计算您获得的数量。如果数字小于该数字,则显示“第1页,共8页”或其他内容。如果数字是151,那么你有超过10页,所以显示“第1页”。这是我在一张桌子上使用的一种方法,它有大约1200万条记录,而且效果非常好。
答案 1 :(得分:4)
您有2个选项。
我更喜欢第二种选择,但就性能而言,它很重要。
答案 2 :(得分:2)
您始终可以对数据进行非规范化。例如,Post
表可以包含CommentsCount
列,该列会在添加和删除注释时更新。
然而,在大多数情况下,这将是一个微观优化,因为每个帖子很少会有大量的评论。
答案 3 :(得分:0)
请使用PEAR's Pager课程。它会自动处理几乎所有内容,您可以使用$pager->getCurrentPageID()
和perPage
属性来获取LIMIT子句。
不重新发明轮子可以节省编码,发现错误和修复错误。