SQLite handles GROUP BY and ORDER BY in basically the same way. If there is an 
apropirate index, then it will use this index and the rows will be returned in 
visitation order of this index. If, for exmaple by adding a new index or even 
an upgrade of the Query Planner, a different execution plan is constructed, 
then the order of the returned rows will "change".

Please note that GROUP BY id,o1,o2 and ORDER BY o1,o2 are DIFFERENT expressions 
and require reordering, which is the reason for an additional BTree step.

If you need the rows to be returned in a specific order, then you must say so 
explicitly with an ORDER BY clause; otherwise, SQLite is free to return rows in 
any order that happens to be convenient for the DB Engine. Relying on the 
"natural" order is a common way of creating code that breaks unexpectedly.

Similarly, if you need the result columns to have certain names, you must 
provide these via AS clauses.

-----Ursprüngliche Nachricht-----
Von: sqlite-users [mailto:sqlite-users-boun...@mailinglists.sqlite.org] Im 
Auftrag von John Found
Gesendet: Sonntag, 16. September 2018 10:30
An: sqlite-users@mailinglists.sqlite.org
Betreff: [EXTERNAL] [sqlite] The "natural" order of the query results.

Is there some relation between the indexes used in the query, the GROUP BY 
fields used and the order of the result rows, when no "ORDER BY" clause is used?

I am asking, because I noticed, that on some queries, when I am using "ORDER 
BY" the query always use temporary b-tree for ordering, but by including the 
needed fields in the "GROUP BY" clause and removing the ORDER BY clause, the 
query returns the rows in the proper order without temp b-tree.

So, is it safe to use this implicit ordering, or this behavior can be changed 
in the future versions of SQLite?

Here is an example:

create table A (
  id integer primary key autoincrement,
  o1 integer,
  o2 integer
);

create table B (
  Aid integer references A(id),
  data text
);

create index idxA on A(o1 desc, o2 desc);

insert into A(o1, o2) values (1, 100), (2, 50), (3, 200), (5, 300); insert into 
B(Aid, data) values (1, "b"), (1, "a"), (2, "c"), (2, "d"), (2, "e"), (3, "f"), 
(3, "g");

-- Always uses temp b-tree for order by
select
  group_concat(B.data), o1, o2
from
  A
left join
  B on A.id = B.Aid
group by
  A.id
order by
  A.o1 desc, A.o2 desc;

explain query plan:
id      parent  notused detail
8       0       0       SCAN TABLE A
19      0       0       SEARCH TABLE B USING AUTOMATIC COVERING INDEX (Aid=?)
58      0       0       USE TEMP B-TREE FOR ORDER BY


-- This one returns the rows in the needed order without ORDER BY select
  group_concat(B.data), o1, o2
from
  A indexed by idxA
left join B on A.id = B.Aid
group by A.id, A.o1, A.o2;

explain query plan:
id      parent  notused detail
7       0       0       SCAN TABLE A USING COVERING INDEX idxA
18      0       0       SEARCH TABLE B USING AUTOMATIC COVERING INDEX (Aid=?)


-- But if I add ORDER BY it still begins to use temp b-tree
-- regardless that it does not change the order.
select
  group_concat(B.data), o1, o2
from
  A indexed by idxA
left join B on A.id = B.Aid
group by A.id, A.o1, A.o2
order by A.o1 desc, A.o2 desc;

explain query plan:
8       0       0       SCAN TABLE A
19      0       0       SEARCH TABLE B USING AUTOMATIC COVERING INDEX (Aid=?)
60      0       0       USE TEMP B-TREE FOR ORDER BY


All the above queries, returns the same result rows in the same order:

group_concat(B.data)  o1   o2
NULL                   5   300
f,g                    3   200
c,d,e                  2   50
a,b                    1   100




--
John Found <johnfo...@asm32.info>
_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


___________________________________________
 Gunter Hick | Software Engineer | Scientific Games International GmbH | 
Klitschgasse 2-4, A-1130 Vienna | FN 157284 a, HG Wien, DVR: 0430013 | (O) +43 
1 80100 - 0

May be privileged. May be confidential. Please delete if not the addressee.
_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to