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毫秒