MySQL数据-实现分页的最佳方式?

ukxgm1gy  于 2022-12-17  发布在  Mysql
关注(0)|答案(9)|浏览(186)

我的iPhone应用程序连接到PHP Web服务以从MySQL数据库检索数据,一个请求最多可以返回500个结果。
实现分页并一次检索20个项目的最佳方法是什么?
假设我从数据库中收到了前20个条目,我现在如何请求接下来的20个条目?

gkn4icbw

gkn4icbw1#

来自MySQL文档:
LIMIT子句可用于约束SELECT语句返回的行数。LIMIT采用一个或两个数值参数,这两个参数必须都是非负整数常量(使用预准备语句时除外)。
使用两个参数,第一个参数指定要返回的第一行的偏移量,第二个参数指定要返回的最大行数。初始行的偏移量为0(而不是1):

SELECT * FROM tbl LIMIT 5,10;  # Retrieve rows 6-15

要检索从某个偏移量到结果集末尾的所有行,可以对第二个参数使用较大的数字。此语句检索从第96行到最后一行的所有行:

SELECT * FROM tbl LIMIT 95,18446744073709551615;

使用一个参数,该值指定从结果集的开头返回的行数:

SELECT * FROM tbl LIMIT 5;     # Retrieve first 5 rows

换句话说,LIMIT row_count等效于LIMIT 0,row_count。

kxe2p93d

kxe2p93d2#

对于500条记录来说,效率可能不是问题,但是如果您有数百万条记录,那么使用WHERE子句选择下一页可能是有利的:

SELECT *
FROM yourtable
WHERE id > 234374
ORDER BY id
LIMIT 20

这里的“234374”是您查看的上一页中最后一条记录的ID。
这样就可以使用id上的索引来查找第一条记录。如果使用LIMIT offset, 20,你会发现当你向末尾翻页时,它会变得越来越慢。正如我所说的,如果你只有200条记录,这可能不会有什么关系,但是对于更大的结果集来说,它会产生影响。
这种方法的另一个优点是,如果数据在两次调用之间发生变化,你不会错过记录或得到重复的记录。这是因为添加或删除一行意味着它之后所有行的偏移量发生了变化。在你的情况下,这可能并不重要--我猜你的广告池不会经常变化,无论如何,没有人会注意到,如果他们在一行中得到相同的广告两次--但如果你“We“如果你在寻找“最佳方法”,那么这是选择使用哪种方法时要记住的另一件事。
如果您确实希望使用带有偏移量的LIMIT(如果用户直接导航到第10000页,而不是逐个分页,则这是必要的),那么您可以阅读这篇关于late row lookups的文章,以提高带有大偏移量的LIMIT的性能。

ve7v8dk2

ve7v8dk23#

为查询定义OFFSET。例如
第1页-(记录01-10):偏移= 0,限值=10;
第2页-(记录11-20)偏移= 10,限制=10;
并使用以下查询:

SELECT column FROM table LIMIT {someLimit} OFFSET {someOffset};

第2页示例:

SELECT column FROM table
LIMIT 10 OFFSET 10;
wvmv3b1j

wvmv3b1j4#

有关于它的文献:

主要问题发生在使用大型OFFSET时。它们通过各种技术避免使用OFFSET,从WHERE子句中的id范围选择到某种缓存或预计算页。
建议的解决方案见使用索引,Luke

wnavrhmk

wnavrhmk5#

本教程介绍了一种很好的分页方法。Efficient Pagination Using MySQL
简而言之,避免使用OFFSET或较大的LIMIT

vfwfrxfs

vfwfrxfs6#

你也可以

SELECT SQL_CALC_FOUND_ROWS * FROM tbl limit 0, 20

select语句的行计数(没有限制)在同一个select语句中捕获,因此您不需要再次查询表的大小。

unftdfkk

unftdfkk7#

查询1:SELECT * FROM yourtable WHERE id > 0 ORDER BY id LIMIT 500
查询2:SELECT * FROM tbl LIMIT 0,500;
查询1对于小记录或中等记录运行得更快,如果记录数等于5,000或更高,则结果相似。

500条记录的结果:

查询1耗时9.9999904632568毫秒
查询2需要19.999980926514毫秒

8,000条记录的结果:

查询1耗时129.99987602234毫秒
查询2需要160.00008583069毫秒

bvjveswy

bvjveswy8#

如果要在存储过程中执行此操作,可以尝试以下操作

SELECT * FROM tbl limit 0, 20.

不幸的是,使用公式不起作用,因此您可以执行一个预准备语句,或者只为过程给予开始值和结束值。

uplii1fm

uplii1fm9#

下面是我使用node.js和MySQL数据库解决这个问题的方法:首先,声明变量!

const 
        Key = payload.Key,
        NumberToShowPerPage = payload.NumberToShowPerPage,
        Offset = payload.PageNumber * NumberToShowPerPage;

NumberToShowPerPage是显而易见的,但偏移量是页码。
现在SQL查询...

pool.query("SELECT * FROM TableName WHERE Key = ? ORDER BY CreatedDate DESC LIMIT ? OFFSET ?", [Key, NumberToShowPerPage, Offset], (err, rows, fields) => {}));

我来解释一下。

  1. Pool,是MySQL连接池,来源于mysql节点包模块,可以使用mysql.createPool创建连接池。
  2. ?被数组[PageKey, NumberToShow, Offset]中的变量按顺序替换,这样做是为了防止SQL注入。
    1.看最后() => {}是什么,这是一个箭头函数,无论你想对数据做什么,把这个逻辑放在括号里。
  3. Key = ?是我用来选择某个外键的东西,如果你不使用外键约束,你可能会删除它。
    希望这个有用。

相关问题