选择最新记录时选择要慢得多

时间:2010-08-24 14:23:53

标签: php sql mysql limit

网站上显示一个大约70K记录的表,每页显示50条记录。 在查询中使用limit offset,50进行分页,并且可以在不同的列上对记录进行排序。

浏览最新页面(因此偏移量大约为60,000)会使查询比浏览第一页(约10倍)时慢得多

这是使用limit命令的问题吗? 还有其他方法可以获得相同的结果吗?

2 个答案:

答案 0 :(得分:7)

对于较大的偏移量,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

有关更详细的说明,请参阅此文章:

答案 1 :(得分:2)

这是MySQL处理限制的方式。如果它可以对索引进行排序(并且查询足够简单),它可以在找到第一个offset + limit行后停止搜索。所以LIMIT 0,10意味着如果查询足够简单,它可能只需要扫描10行。但LIMIT 1000,10表示至少需要扫描1010行。当然,需要扫描的实际行数取决于许多其他因素。但这里的要点是limit + offset越低,需要扫描的行数下限就越低......

至于变通方法,我会优化您的查询,以便不带LIMIT子句的查询本身尽可能高效。 EXPLAIN在这种情况下你是朋友......