LIMIT和OFFSET ================== ``LIMIT``\ 和\ ``OFFSET``\ 允许你只检索查询剩余部分产生的行的一部分: .. code:: synopsis SELECT select_list FROM table_expression [ ORDER BY ... ] [ LIMIT { number | ALL } ] [ OFFSET number ] 如果给出了一个限制计数,那么会返回数量不超过该限制的行(但可能更少些,因为查询本身可能生成的行数就比较少)。\ ``LIMIT ALL``\ 的效果和省略\ ``LIMIT``\ 子句一样,就像是\ ``LIMIT``\ 带有 NULL 参数一样。 ``OFFSET``\ 说明在开始返回行之前忽略多少行。\ ``OFFSET 0``\ 的效果和省略\ ``OFFSET``\ 子句是一样的,并且\ ``LIMIT NULL``\ 的效果和省略\ ``LIMIT``\ 子句一样,就像是\ ``OFFSET``\ 带有 NULL 参数一样。 如果\ ``OFFSET``\ 和\ ``LIMIT``\ 都出现了, 那么在返回\ ``LIMIT``\ 个行之前要先忽略\ ``OFFSET``\ 行。 如果使用\ ``LIMIT``\ ,那么用一个\ ``ORDER BY``\ 子句把结果行约束成一个唯一的顺序是很重要的。否则你就会拿到一个不可预料的该查询的行的子集。你要的可能是第十到第二十行,但以什么顺序的第十到第二十?除非你指定了\ ``ORDER BY``\ ,否则顺序是不知道的。 查询优化器在生成查询计划时会考虑\ ``LIMIT``\ ,因此如果你给定\ ``LIMIT``\ 和\ ``OFFSET``\ ,那么你很可能收到不同的规划(产生不同的行顺序)。因此,使用不同的\ ``LIMIT``/``OFFSET``\ 值选择查询结果的不同子集\ *将生成不一致的结果*\ ,除非你用\ ``ORDER BY``\ 强制一个可预测的顺序。这并非bug, 这是一个很自然的结果,因为 SQL 没有许诺把查询的结果按照任何特定的顺序发出,除非用了\ ``ORDER BY``\ 来约束顺序。 被\ ``OFFSET``\ 子句忽略的行仍然需要在服务器内部计算;因此,一个很大的\ ``OFFSET``\ 的效率可能还是不够高。