在使用SQL查询时,对网站进行分页的最有效方法是什么?

时间:2008-09-09 19:40:42

标签: php sql sqlite pdo

我正在尝试对SQL查询的结果进行分页,以便在网页上使用。语言和数据库后端是PHP和SQLite。

我正在使用的代码是这样的(页面编号从0开始)

http://example.com/table?page=0

page = request(page)
per = 10 // results per page
offset = page * per

// take one extra record so we know if a next link is needed
resultset = query(select columns from table where conditions limit offset, per + 1)

if(page > 0) show a previous link
if(count(resultset) > per) show a next link

unset(resultset[per])

display results

是否有比这更有效的分页方式?

我可以通过当前方法看到的一个问题是,在开始显示之前,我必须将所有10个(或多个)结果存储在内存中。我这样做是因为PDO不保证行数可用。

发出COUNT(*)查询以了解存在多少行,然后将结果流式传输到浏览器是否更有效?

这是“这取决于你的表的大小,以及count(*)查询是否需要在数据库后端进行全表扫描”,“自己做一些分析”这类问题吗?

4 个答案:

答案 0 :(得分:2)

我选择使用COUNT(*)两种查询方法,因为它允许我直接创建到最后一页的链接,而另一种方法不允许。首先执行计数也允许我流式传输结果,因此应该使用更少数量的内存更少的记录。

页面之间的一致性对我来说不是问题。谢谢你的帮助。

答案 1 :(得分:2)

在某些情况下,我有一个相当复杂的(9-12表连接)查询,返回数千行,我需要对其进行分页。显然要很好地分页,你需要知道结果的总大小。使用MySQL数据库,在SELECT中使用SQL_CALC_FOUND_ROWS指令可以帮助您轻松实现这一目标,尽管评委会对您是否会更有效率进行评估。

但是,由于您使用的是SQLite,我建议坚持使用2查询方法。 Here是一个非常简洁的问题。

答案 2 :(得分:1)

我建议先做点算。 count(主键)是一种非常有效的查询。

答案 3 :(得分:1)

我怀疑用户等待后端返回十行会有问题。 (您可以通过擅长指定图像尺寸,使网络服务器尽可能协商压缩数据传输等来完成它们。)

我认为最初做计数(*)对你来说非常有用。

如果您需要进行一些复杂的编码:当用户查看第x页时,请使用类似于jax的魔术来预加载页面x + 1,以改善用户体验。

关于分页的一般说明: 如果在用户浏览您的网页时数据发生变化,那么如果您的解决方案需要非常高的一致性,则可能会成为问题。我写了一篇关于elsewhere的说明。