我正在尝试对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(*)
查询是否需要在数据库后端进行全表扫描”,“自己做一些分析”这类问题吗?
答案 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的说明。