在一个站点上显示一个包含约70K条记录的表格,每页显示50条记录。 在查询上使用limit offset,50
完成分页,并且记录可以在不同的列上排序。选择最新记录时选择速度要慢很多
浏览最新的页面(因此偏移约60,000)使得查询慢得多浏览前几页(约10倍)
这是使用limit
命令的一个问题,当比? 是否有其他方法可以获得相同的结果?
在一个站点上显示一个包含约70K条记录的表格,每页显示50条记录。 在查询上使用limit offset,50
完成分页,并且记录可以在不同的列上排序。选择最新记录时选择速度要慢很多
浏览最新的页面(因此偏移约60,000)使得查询慢得多浏览前几页(约10倍)
这是使用limit
命令的一个问题,当比? 是否有其他方法可以获得相同的结果?
随着较大的偏移量,MySQL
需要浏览更多的记录。
即使计划使用filesort
(这意味着所有的记录应该浏览),MySQL
优化,这样只有$offset + $limit
最高记录进行排序,这使得它更加高效为$offset
较低值。
典型的解决方案是索引您订购的列,记录列的最后一个值,并在随后的查询重用,像这样:
SELECT *
FROM mytable
ORDER BY
value, id
LIMIT 0, 10
,输出:
value id
1 234
3 57
4 186
5 457
6 367
8 681
10 366
13 26
15 765
17 345 -- this is the last one
要进入下一个页面,你可以使用:
SELECT *
FROM mytable
WHERE (value, id) > (17, 345)
ORDER BY
value, id
LIMIT 0, 10
,它采用了在请登录(value, id)
查询。
当然这不会对任意访问页面有所帮助,但有助于顺序浏览。
另外,MySQL
在后期查询中存在一些问题。如果列索引,它可能是值得尝试重写查询是这样的:
SELECT *
FROM (
SELECT id
FROM mytable
ORDER BY
value, id
LIMIT $offset, $limit
) q
JOIN mytable m
ON m.id = q.id
请参阅这篇文章更详细的解释:
MySQL支持元组式样的语法('(val1,val2)>(1,2)')?我以前从来没有见过。什么是组合器(和,我假设)?我想你每天都会学到新的东西...... – ircmaxell 2010-08-24 14:40:41
@ircmaxell:是的。它是字典顺序,与val1> 1 OR(val1 = 1 AND val2> 2)相同' – Quassnoi 2010-08-24 14:42:19
好的答案。这里是一个演示,我认为有一些很好的信息是沿着相同的路线:http://www.slideshare.net/Eweaver/efficient-pagination-using-mysql – nathan 2010-08-24 18:42:01
这是MySQL如何处理限制。如果它可以对索引进行排序(并且查询足够简单),则可以在找到第一个offset + limit
行后停止搜索。所以LIMIT 0,10
意味着如果查询很简单,它可能只需要扫描10行。但LIMIT 1000,10
意味着至少需要扫描1010行。当然,需要扫描的实际行数取决于许多其他因素。但重点在于,limit + offset
越低,需要扫描的行数越低...
至于变通方法,我会优化您的查询,以便查询本身没有LIMIT
子句尽可能高效。 EXPLAIN
是你在这种情况下的朋友...
好问题,我不熟悉MySQL在这方面的工作原理。 – RedFilter 2010-08-24 14:26:05
感谢你的回复,稍后会测试它,希望能获得一些速度。 – Omiod 2010-08-24 16:07:28