Ken wrote:
> select * from foo
> where rowid =
> (select rowid from foo
> where parent_id = 1
> and child_id = 2
> group by parent_id, child_id
> having revision = max(revision))
>
> sqlite> explain query plan
> ...> select * from foo
> ...> where rowid =
> ...> (select rowid from foo
> ...> where parent_id = 1
> ...> and child_id = 2
> ...> group by parent_id, child_id
> ...> having revision = max(revision))
> ...> ;
> order|from|detail
> 0|0|TABLE foo USING PRIMARY KEY
> 0|0|TABLE foo WITH INDEX FOO_IDX1 ORDER BY
>
>
> Would the above be faster due to the use of the PRIMARY key access ?
>
Ken,
I'm not sure about the general case, but in this case I suspect not
because of SQLite's index data optimization.
If all the required columns can be returned from an index, then SQLite
will pull the data from the index and never actually reference the base
table. That condition is true here since all the column are in the index.
I have copied the explain output for both queries below. My query looks
more direct and uses the index optimization to return the data. I would
have to measure the actual execution time to be sure, but I suspect it
will execute faster as well.
C:\Documents and Settings\DennisC>sqlite3
SQLite version 3.5.6
Enter ".help" for instructions
sqlite>
sqlite> CREATE TABLE if not exists FOO (
...> PARENT_ID INTEGER,
...> CHILD_ID INTEGER,
...> REVISION INTEGER
...> );
sqlite>
sqlite> CREATE UNIQUE INDEX FOO_IDX1 ON FOO (PARENT_ID,CHILD_ID,REVISION);
sqlite>
sqlite> .explain
sqlite> explain
...> select * from foo
...> where parent_id = :parentId
...> and child_id = :childId
...> and revision =
...> (select max(revision) from foo
...> where parent_id = :parentId
...> and child_id = :childId)
...> ;
addr opcode p1 p2 p3 p4 p5 comment
---- ------------- ---- ---- ---- ------------- -- -------------
0 Trace 0 0 0 explain
select * from foo
where parent_id = :parentId
and child_id = :childId
and revision =
(select max(revision) from foo
where parent_id = :parentId
and child_id = :childId)
; 00
1 Goto 0 48 0 00
2 OpenRead 2 3 0 keyinfo(3,BINARY,BINARY) 00
3 SetNumColumns 2 4 0 00
4 Variable 1 2 0 :parentId 00
5 IsNull 2 46 0 00
6 Variable 2 3 0 :childId 00
7 IsNull 3 46 0 00
8 If 7 36 0 00
9 Integer 1 7 0 00
10 Null 0 8 0 00
11 Integer 1 9 0 00
12 MustBeInt 9 0 0 00
13 IfZero 9 36 0 00
14 Null 0 11 0 00
15 Null 0 10 0 00
16 OpenRead 3 3 0 keyinfo(3,BINARY,BINARY) 00
17 SetNumColumns 3 4 0 00
18 Variable 1 13 0 :parentId 00
19 IsNull 13 30 0 00
20 Variable 2 14 0 :childId 00
21 IsNull 14 30 0 00
22 MakeRecord 13 2 12 dddb 00
23 MoveLe 3 30 12 00
24 IdxLT 3 30 12 00
25 Column 3 2 17 00
26 CollSeq 0 0 0 collseq(BINARY) 00
27 AggStep 0 17 10 max(1) 01
28 Goto 0 30 0 00
29 Prev 3 24 0 00
30 Close 3 0 0 00
31 AggFinal 10 1 0 max(1) 00
32 SCopy 10 17 0 00
33 Move 17 8 0 00
34 AddImm 9 -1 0 00
35 IfZero 9 36 0 00
36 SCopy 8 4 0 00
37 IsNull 4 46 0 00
38 MakeRecord 2 3 1 dddb 00
39 MoveGe 2 46 1 00
40 IdxGE 2 46 1 01
41 Column 2 0 18 00
42 Column 2 1 19 00
43 Column 2 2 20 00
44 ResultRow 18 3 0 00
45 Next 2 40 0 00
46 Close 2 0 0 00
47 Halt 0 0 0 00
48 Transaction 0 0 0 00
49 VerifyCookie 0 2 0 00
50 TableLock 0 2 0 FOO 00
51 Goto 0 2 0 00
sqlite> explain query plan
...> select * from foo
...> where parent_id = :parentId
...> and child_id = :childId
...> and revision =
...> (select max(revision) from foo
...> where parent_id = :parentId
...> and child_id = :childId)
...> ;
orde from deta
---- ------------- ----
0 0 TABLE foo WITH INDEX FOO_IDX1
0 0 TABLE foo WITH INDEX FOO_IDX1 ORDER BY
sqlite>
sqlite>
sqlite>
sqlite> explain
...> select * from foo
...> where rowid =
...> (select rowid from foo
...> where parent_id = 1
...> and child_id = 2
...> group by parent_id, child_id
...> having revision = max(revision))
...> ;
addr opcode p1 p2 p3 p4 p5 comment
---- ------------- ---- ---- ---- ------------- -- -------------
0 Trace 0 0 0 explain
select * from foo
where rowid =
(select rowid from foo
where parent_id = 1
and child_id = 2
group by parent_id, child_id
having revision = max(revision))
; 00
1 Goto 0 66 0 00
2 OpenRead 0 2 0 00
3 SetNumColumns 0 3 0 00
4 If 2 57 0 00
5 Integer 1 2 0 00
6 Null 0 3 0 00
7 Integer 1 4 0 00
8 MustBeInt 4 0 0 00
9 IfZero 4 57 0 00
10 Noop 0 0 0 00
11 Integer 0 9 0 00
12 Integer 0 8 0 00
13 Goto 0 29 0 00
14 Integer 1 9 0 00
15 Return 0 0 0 00
16 IfPos 8 18 0 00
17 Return 0 0 0 00
18 AggFinal 7 1 0 max(1) 00
19 Ne 7 17 6 collseq(BINARY) 6c
20 SCopy 5 15 0 00
21 Move 15 3 0 00
22 AddImm 4 -1 0 00
23 IfZero 4 14 0 00
24 Return 0 0 0 00
25 Null 0 5 0 00
26 Null 0 6 0 00
27 Null 0 7 0 00
28 Return 0 0 0 00
29 Gosub 0 25 0 00
30 OpenRead 3 3 0 keyinfo(3,BINARY,BINARY) 00
31 SetNumColumns 3 4 0 00
32 Integer 1 17 0 00
33 IsNull 17 55 0 00
34 Integer 2 18 0 00
35 IsNull 18 55 0 00
36 MakeRecord 17 2 16 dddb 00
37 MoveGe 3 55 16 00
38 IdxGE 3 55 16 01
39 Column 3 0 12 00
40 Column 3 1 13 00
41 Ne 11 43 13 collseq(BINARY) 10
42 Eq 10 48 12 collseq(BINARY) 10
43 Move 12 10 0 00
44 Move 13 11 0 00
45 Gosub 0 16 0 00
46 IfPos 9 57 0 00
47 Gosub 0 25 0 00
48 Column 3 2 15 00
49 CollSeq 0 0 0 collseq(BINARY) 00
50 AggStep 0 15 7 max(1) 01
51 IdxRowid 3 5 0 00
52 Column 3 2 6 00
53 Integer 1 8 0 00
54 Next 3 38 0 00
55 Close 3 0 0 00
56 Gosub 0 16 0 00
57 SCopy 3 1 0 00
58 MustBeInt 1 64 1 00
59 NotExists 0 64 1 00
60 Column 0 0 21 00
61 Column 0 1 22 00
62 Column 0 2 23 00
63 ResultRow 21 3 0 00
64 Close 0 0 0 00
65 Halt 0 0 0 00
66 Transaction 0 0 0 00
67 VerifyCookie 0 2 0 00
68 TableLock 0 2 0 FOO 00
69 Goto 0 2 0 00
sqlite> explain query plan
...> select * from foo
...> where rowid =
...> (select rowid from foo
...> where parent_id = 1
...> and child_id = 2
...> group by parent_id, child_id
...> having revision = max(revision))
...> ;
orde from deta
---- ------------- ----
0 0 TABLE foo USING PRIMARY KEY
0 0 TABLE foo WITH INDEX FOO_IDX1 ORDER BY
sqlite>
sqlite>
_______________________________________________
sqlite-users mailing list
[email protected]
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users