在大多数数据库中,带有偏移量的LIMIT极其慢(我已经找到了一些
有关MySQL的文档,并且我试图找到我之前读过的关于SQLite的一篇很好的文章)。原因是通常已实现了以下内容:
- 进行所有常规查询计划,就好像该
LIMIT
子句不在那儿一样 - 浏览结果,直到找到所需的索引
- 开始返回结果
如果您这样做
LIMIT 10000, 10,这意味着什么,它将被解释为:
- 提取前10,000个结果并忽略它们
- 给你接下来的10个结果
有一个微不足道的优化方法,因为您不关心它们的值,所以您至少可以对前10,000个结果使用索引,但是即使在那种情况下,数据库仍然需要遍历10,000个索引值才能给您10个结果。可能还有进一步的优化可以改善这一点,但是通常情况下,
您不想LIMIT
对大值使用偏移量。
我知道,处理分页的最有效方法是跟踪最后一个索引,因此,如果第一个页面以结尾
id = 5,则使您的 下一个 链接具有
WHERe id >5(
LIMIT x当然带有)。
编辑:找到了SQLite的文章。我强烈建议您阅读此书,因为它解释了在SQL中执行操作的正确方法。由于SQLite的人
真的很聪明, 而其他数据库也有同样的问题,因此我认为MySQL以类似的方式实现了这一点。
经常出现的另一个错误是程序员尝试使用LIMIT和OFFSET实现滚动窗口。这里的想法是,您首先只需要记住显示中顶部条目的索引,然后运行如下查询:
SELECt title FROM tracksWHERe singer='Madonna'ORDER BY titleLIMIT 5 OFFSET :index索引初始化为0。要向下滚动,只需将索引增加5并重新运行查询即可。要向上滚动,请将索引递减5并重新运行。
以上将实际工作。 问题是当索引变大时它变慢。
OFFSET在SQLite中的工作方式是使sqlite3_step()函数忽略它看到的第一个:index断点。因此,例如,如果:index为1000,则您实际上是在读1005个条目,而忽略除最后5个之外的所有条目。最终的结果是,随着列表中的位置越来越低,滚动开始变得缓慢。



