嗨我有一个包含实体的表,id是从序列生成的
我的表中有超过2个条目,现在我想浏览所有元素。但
LIMIT 100 OFFSET 2000000
对我来说太慢了,所以我尝试了两种不同的语句(伪代码)
int i = 0;
while(true) {
a: SELECT * FROM entity WHERE id>=i ORDER BY id LIMIT 100
b: SELECT * FROM (SELECT * FROM entity ORDER BY id)a WHERE id>=i LIMIT 100
i=<id of last fetched row>;
}
两个查询都很快,似乎显示出正确的结果......但我有一种预感,一个不会总是有效...任何想法?我需要订购吗?
答案 0 :(得分:0)
是order by
的查询位置确实无关紧要。 AFAIK,在SQL规范中,如果您未在最外层查询中指定order by
,则根本无法保证结果集中的行顺序。有时候你可以按照自己的意愿订购行,但不能保证。
要显示它,这是一个小测试 - 假设我们有这样的表test
:
create table test(id int, name text);
insert into test
select 1, 'John' union all
select 2, 'Adele';
现在让我们运行一些查询。这个工作正常(由order by
保证):
select * from test as t1 order by t1.name;
id name
-----------
2 Adele
1 John
这个工作正常几乎可以肯定,它是从有序子查询中选择的,SQL没有理由重新排序:
select * from (select * from test order by name) as t1
id name
-----------
2 Adele
1 John
但是假设我们必须在此查询中使用自联接。这个也将正常工作(由order by
保证):
select *
from test as t1
inner join test as t2 on t2.id = t1.id
order by t1.name;
id name
-----------
2 Adele
1 John
但由于merge join
,这个会被重新排序。 SQL必须在合并连接期间按连接列对集合进行排序,以便重新排序t1
,并且由于您未指定外部order by
,因此将返回id
排序的结果:
select *
from (select * from test order by name) as t1
inner join test as t2 on t2.id = t1.id;
id name
-----------
1 John
2 Adele
<强> sql fiddle demo 强>
对于原始问题,如果您的选择之间发生了一些数据修改,即使在最外层查询中指定order by
也无效。