我正在尝试对 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(*) 查询需要在数据库后端进行全表扫描”、“自己做一些分析”之类的问题?

有帮助吗?

解决方案

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

其他提示

我选择使用 COUNT(*) 两种查询方法,因为它允许我创建直接到最后一页的链接,而其他方法不允许这样做。首先执行计数还允许我流式传输结果,因此应该可以在内存较少的情况下很好地处理大量记录。

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

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

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

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

我认为最初执行 count(*) 对您来说不是很有用。

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

关于分页的一般注意事项:如果数据在用户浏览您的页面时发生变化, 可能 如果您的解决方案需要非常高的一致性,这就会成为一个问题。我已经为此写了一篇笔记 别处.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top