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

我的iPhone应用程序连接到我的PHP Web服务从MySQL数据库检索数据。 一个请求可以返回500个结果。

什么是一次实现分页和检索20个项目的最佳方式?

比方说,我收到了我的数据库中的前20个广告。 现在我怎么能要求下20个广告?

从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。

对于500条logging,效率可能不是问题,但是如果您有数百万条logging,那么使用WHERE子句select下一个页面可能是有利的:

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

这里的“234374”是您查看的首页的最后一条logging的ID。

这将使id上的索引被用来查找第一条logging。 如果使用LIMIT offset, 20可以发现在页面朝向结尾时,它会变得越来越慢。 正如我所说,如果只有200条logging,这可能并不重要,但是对于更大的结果集可能会有所不同。

这种方法的另一个好处是,如果数据在调用之间改变,您将不会错过logging或重复logging。 这是因为添加或删除行意味着所有行在其更改后的偏移量。 在你的情况下,这可能并不重要 – 我想你的广告池不会变得太频繁,反正没有人会注意到,如果他们连续两次得到相同的广告 – 但如果你正在寻找“最好的方式”那么在select使用哪种方法时,要记住这一点。

如果您希望使用偏移量(如果用户直接导航到页面10000而不是通过页面逐页进行分页,则这是必需的),那么您可以阅读关于后期查找的文章,以提高LIMIT的性能抵消。

本教程展示了一种分页的好方法。 使用MySQL高效分页

总之,避免使用OFFSET或大LIMIT

有关于它的文献:

  • 使用MySQL进行优化分页 ,使计算行总数和分页之间的区别。

  • 在Percona Performance Conference 2009上由Yahoo Inc. 使用MySQL进行高效分页 .Percona MySQL团队还将其作为Youtubevideo提供: 使用MySQL(video)的高效分页 ,

主要的问题是使用大的OFFSET 。 他们避免使用OFFSET的各种技术,从WHERE子句中的id范围select,到某种caching或预计算页面。

使用INDEX,卢克build议的解决scheme:

  • “ 通过结果寻找 ”。

  • “ 分页完成正确的方式 ”。

为查询定义OFFSET 。 例如

第1页 – (logging01-10):offset = 0,limit = 10;

第2页 – (logging11-20)偏移= 10,限制= 10;

并使用以下查询:

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

第2页的示例:

 SELECT column FROM table LIMIT 10 OFFSET 10; 

你也可以做

 SELECT SQL_CALC_FOUND_ROWS * FROM tbl limit 0, 20 

select语句的行数(没有限制)在同一个select语句中被捕获,所以你不需要再次查询表的大小。 你使用SELECT FOUND_ROWS()获得行数。

查询1: SELECT * FROM yourtable WHERE id > 0 ORDER BY id LIMIT 500

查询2: SELECT * FROM tbl LIMIT 0,500;

如果logging数等于或高于5000,结果是相似的,则查询1以小logging或中logging运行得更快。

500条logging的结果:

Query1取9.9999904632568毫秒

Query2取19.999980926514毫秒

8000条logging的结果:

Query1采取129.99987602234毫秒

Query2需要160.00008583069毫秒