2008-09-09 39 views
0

我想分页SQL查询的结果在网页上使用。语言和数据库后端是PHP和SQLite。SQL分页

的代码我使用的作品像这样的东西(页编号从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不能保证rowcount可用。

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

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

回答

1

我建议只是先计数。计数(主键)是一个非常有效的查询。

+4

...只要不过滤没有索引的列(WHERE)并且不使用连接:) – BlaM 2008-09-10 07:53:04

1

我怀疑这对你的用户来说是一个等待后端返回10行的问题。 (你可以通过擅长指定图像尺寸,让网络服务器在可能的时候协商压缩数据传输等来弥补它们的不足)。

我不认为它会对你做一个计数非常有用(*) 原来。

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

约分页的一般注意事项: 如果数据的变化,而用户通过网页浏览,也可以一个问题,如果您的解决方案要求的一致性非常高的水平。我写了一个关于elsewhere的笔记。

2

我选择使用COUNT(*)两种查询方法,因为它允许我直接创建一个链接到最后一页,而另一个方法不允许。首先执行计数还允许我分配结果,因此应该使用更少的内存更好地处理更多的记录。

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

2

有几种情况下,我有一个相当复杂的(9-12表连接)查询,返回数以千计的行,我需要分页。很明显,对于分页很好,你需要知道结果的总大小。对于MySQL数据库,在SELECT中使用SQL_CALC_FOUND_ROWS指令可以帮助您轻松实现这一目标,尽管评审团已经决定是否可以提高效率。

但是,由于您正在使用SQLite,我建议坚持使用2查询方法。 Here是关于此事的非常简洁的线索。