Let's create and populate a test table:

sqlite> CREATE TABLE foo (id INTEGER PRIMARY KEY NOT NULL);
sqlite> INSERT INTO foo VALUES (1);
sqlite> INSERT INTO foo VALUES (100);
sqlite> INSERT INTO foo VALUES (200);
sqlite> INSERT INTO foo SELECT MAX (id) + 1 FROM foo WHERE id >= 100 AND 
id < 200;
sqlite> INSERT INTO foo SELECT MAX (id) + 1 FROM foo WHERE id >= 100 AND 
id < 200;
sqlite> INSERT INTO foo SELECT MAX (id) + 1 FROM foo WHERE id >= 100 AND 
id < 200;

Now, querying for MAX (id) in an id range gives, I think, a suboptimal plan,
traversing all the entries in the foo between 200 and 100, but what is
interesting is that it starts with the greatest id (SeekLt):

sqlite> explain SELECT MAX (id) FROM foo WHERE id >= 100 AND id < 200;
addr  opcode         p1    p2    p3    p4             p5  comment
----  -------------  ----  ----  ----  -------------  --  -------------
0     Trace          0     0     0                    00
1     Null           0     2     0                    00
2     Null           0     1     0                    00
3     Integer        100   3     0                    00
4     Integer        200   4     0                    00
5     Goto           0     21    0                    00
6     OpenRead       0     2     0     0              00
7     SeekLt         0     16    4                    00
8     SCopy          3     6     0                    00
9     Rowid          0     5     0                    00
10    Lt             6     16    5                    6b
11    Rowid          0     7     0                    00
12    CollSeq        0     0     0     collseq(BINARY)  00
13    AggStep        0     7     1     max(1)         01
14    Goto           0     16    0                    00
15    Prev           0     9     0                    00
16    Close          0     0     0                    00
17    AggFinal       1     1     0     max(1)         00
18    SCopy          1     8     0                    00
19    ResultRow      8     1     0                    00
20    Halt           0     0     0                    00
21    Transaction    0     0     0                    00
22    VerifyCookie   0     3     0                    00
23    TableLock      0     2     0     foo            00
24    Goto           0     6     0                    00

Whereas querying for MAX (id) + 1 makes it start from the lowest id and 
go forward:

sqlite> explain SELECT MAX (id) + 1 FROM foo WHERE id >= 100 AND id < 200;
addr  opcode         p1    p2    p3    p4             p5  comment
----  -------------  ----  ----  ----  -------------  --  -------------
0     Trace          0     0     0                    00
1     Null           0     2     0                    00
2     Null           0     1     0                    00
3     Integer        100   3     0                    00
4     Integer        200   4     0                    00
5     Goto           0     21    0                    00
6     OpenRead       0     2     0     0              00
7     SeekGe         0     15    3                    00
8     SCopy          4     6     0                    00
9     Rowid          0     5     0                    00
10    Ge             6     15    5                    6b
11    Rowid          0     7     0                    00
12    CollSeq        0     0     0     collseq(BINARY)  00
13    AggStep        0     7     1     max(1)         01
14    Next           0     9     0                    00
15    Close          0     0     0                    00
16    AggFinal       1     1     0     max(1)         00
17    Integer        1     5     0                    00
18    Add            5     1     8                    00
19    ResultRow      8     1     0                    00
20    Halt           0     0     0                    00
21    Transaction    0     0     0                    00
22    VerifyCookie   0     3     0                    00
23    TableLock      0     2     0     foo            00
24    Goto           0     6     0                    00

I wonder why it is.
Of course, to get an optimal plan for this one would need to write
SELECT id + 1 FROM foo WHERE id >= 100 AND id < 200 ORDER BY id DESC 
LIMIT 1;
but I wonder if the difference between MAX (id) and MAX (id) + 1 is an
unfinished attempt at a special case optimization for MAX.

Also, it would be nice and intuitive if the MAX (id) and MAX (id) + 1 worked
optimally within a range!
_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to