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

Posted

技术标签:

【中文标题】使用 SQL 查询时,对我的网站进行分页的最有效方法是啥?【英文标题】:What is the most efficient way to paginate my site when querying with SQL?使用 SQL 查询时,对我的网站进行分页的最有效方法是什么? 【发布时间】:2010-09-08 08:08:15 【问题描述】:

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

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

【参考方案2】:

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

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

【讨论】:

【参考方案3】:

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

【讨论】:

...只要您不在没有索引的列上过滤(WHERE)并且不使用连接:)【参考方案4】:

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

我不认为最初做一个 count(*) 对你很有用。

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

关于分页的一般说明: 如果在用户浏览您的页面时数据发生变化,如果您的解决方案需要非常高的一致性水平,可能就会出现问题。我已经写了一个关于 elsewhere 的注释。

【讨论】:

以上是关于使用 SQL 查询时,对我的网站进行分页的最有效方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

带有分页的MySql查询中的随机值

java分页

SQL---分页查询

在Django REST List API视图中对原始SQL查询进行分页的最佳方法是什么?

SQL Server 2012 实现分页新语法

SQL 查询优化