Looks correct to me.  There are only two loops required.  One to loop through 
em (which will only find at most one matching row in lo, so no need for a loop 
there), and another to loop through mny (which will find at most one matching 
row in ldv, so no need to loop there).  The cross-product of those two loops is 
then returned.

SQLite version 3.8.9 2015-03-16 20:40:00
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> create table em(name int primary key,age int);
sqlite> create table idv(id int primary key,name text);
sqlite> create table mny(id int primary key,sal int);
sqlite> create table lo(name int primary key,addr text);
sqlite>
sqlite> insert into em values(44,21);
sqlite> insert into em values(11,20);
sqlite> insert into em values(5,20);
sqlite> insert into idv values(11,44);
sqlite> insert into idv values(5,11);
sqlite> insert into idv values(44,180);
sqlite> insert into mny values(5,10000);
sqlite> insert into mny values(11,5000);
sqlite> insert into mny values(44,5000);
sqlite> insert into lo values(5,'NY');
sqlite> insert into lo values(44,'che');
sqlite> insert into lo values(11,'NY');
sqlite>
sqlite> .eqp on
sqlite> select * from em,lo,mny,idv where lo.name=em.name and idv.id=mny.id;
--EQP-- 0,0,0,SCAN TABLE em
--EQP-- 0,1,1,SEARCH TABLE lo USING INDEX sqlite_autoindex_lo_1 (name=?)
--EQP-- 0,2,2,SCAN TABLE mny
--EQP-- 0,3,3,SEARCH TABLE idv USING INDEX sqlite_autoindex_idv_1 (id=?)
44|21|44|che|5|10000|5|11
44|21|44|che|11|5000|11|44
44|21|44|che|44|5000|44|180
11|20|11|NY|5|10000|5|11
11|20|11|NY|11|5000|11|44
11|20|11|NY|44|5000|44|180
5|20|5|NY|5|10000|5|11
5|20|5|NY|11|5000|11|44
5|20|5|NY|44|5000|44|180
sqlite>
sqlite> .explain
sqlite> explain select * from em,lo,mny,idv where lo.name=em.name and 
idv.id=mny.id;
addr  opcode         p1    p2    p3    p4             p5  comment
----  -------------  ----  ----  ----  -------------  --  -------------
0     Init           0     55    0                    00  Start at 55
1     OpenRead       0     2     0     2              00  root=2 iDb=0; em
2     OpenRead       1     8     0     2              00  root=8 iDb=0; lo
3     OpenRead       4     9     0     k(2,nil,nil)   00  root=9 iDb=0; 
sqlite_autoindex_lo_1
4     OpenRead       2     6     0     2              00  root=6 iDb=0; mny
5     OpenRead       3     4     0     2              00  root=4 iDb=0; idv
6     OpenRead       5     5     0     k(2,nil,nil)   00  root=5 iDb=0; 
sqlite_autoindex_idv_1
7     Explain        0     0     0     SCAN TABLE em  00
8     Noop           0     0     0                    00  Begin WHERE-loop0: em
9     Rewind         0     47    0                    00
10      Explain        0     1     1     SEARCH TABLE lo USING INDEX 
sqlite_autoindex_lo_1 (name=?)  00
11      Noop           0     0     0                    00  Begin WHERE-loop1: 
lo
12      Column         0     0     1                    00  r[1]=em.name
13      IsNull         1     45    0                    00  if r[1]==NULL goto 
45
14      Affinity       1     1     0     D              00  affinity(r[1])
15      SeekGE         4     45    1     1              00  key=r[1]
16      IdxGT          4     45    1     1              00  key=r[1]
17      IdxRowid       4     2     0                    00  r[2]=rowid
18      Seek           1     2     0                    00  intkey=r[2]
19      Explain        0     2     2     SCAN TABLE mny  00
20      Noop           0     0     0                    00  Begin WHERE-loop2: 
mny
21      Rewind         2     44    0                    00
22        Explain        0     3     3     SEARCH TABLE idv USING INDEX 
sqlite_autoindex_idv_1 (id=?)  00
23        Noop           0     0     0                    00  Begin 
WHERE-loop3: idv
24        Column         2     0     3                    00  r[3]=mny.id
25        IsNull         3     42    0                    00  if r[3]==NULL 
goto 42
26        Affinity       3     1     0     D              00  affinity(r[3])
27        SeekGE         5     42    3     1              00  key=r[3]
28        IdxGT          5     42    3     1              00  key=r[3]
29        IdxRowid       5     4     0                    00  r[4]=rowid
30        Seek           3     4     0                    00  intkey=r[4]
31        Noop           0     0     0                    00  Begin WHERE-core
32        Column         0     0     5                    00  r[5]=em.name
33        Column         0     1     6                    00  r[6]=em.age
34        Column         4     0     7                    00  r[7]=lo.name
35        Column         1     1     8                    00  r[8]=lo.addr
36        Column         2     0     9                    00  r[9]=mny.id
37        Column         2     1     10                   00  r[10]=mny.sal
38        Column         5     0     11                   00  r[11]=idv.id
39        Column         3     1     12                   00  r[12]=idv.name
40        ResultRow      5     8     0                    00  output=r[5..12]
41        Noop           0     0     0                    00  End WHERE-core
42        Noop           0     0     0                    00  End WHERE-loop3: 
idv
43      Next           2     22    0                    01
44      Noop           0     0     0                    00  End WHERE-loop2: mny
45      Noop           0     0     0                    00  End WHERE-loop1: lo
46    Next           0     10    0                    01
47    Noop           0     0     0                    00  End WHERE-loop0: em
48    Close          0     0     0                    00
49    Close          1     0     0                    00
50    Close          4     0     0                    00
51    Close          2     0     0                    00
52    Close          3     0     0                    00
53    Close          5     0     0                    00
54    Halt           0     0     0                    00
55    Transaction    0     0     4     0              01
56    TableLock      0     2     0     em             00  iDb=0 root=2 write=0
57    TableLock      0     8     0     lo             00  iDb=0 root=8 write=0
58    TableLock      0     6     0     mny            00  iDb=0 root=6 write=0
59    TableLock      0     4     0     idv            00  iDb=0 root=4 write=0
60    Goto           0     1     0                    00
sqlite>

---
Theory is when you know everything but nothing works.  Practice is when 
everything works but no one knows why.  Sometimes theory and practice are 
combined:  nothing works and no one knows why.

>-----Original Message-----
>From: sqlite-users-bounces at mailinglists.sqlite.org [mailto:sqlite-users-
>bounces at mailinglists.sqlite.org] On Behalf Of Sairam Gaddam
>Sent: Tuesday, 17 March, 2015 06:42
>To: General Discussion of SQLite Database
>Subject: Re: [sqlite] regarding loops in vdbe code
>
>But in my example there are multiple rows which satisfy the condition.
>
>My example:
>
>sql="create table em(name int primary key,age int);"\
>    "create table idv(id int primary key,name text);"\
>    "create table mny(id int primary key,sal int);"\
>    "create table lo(name int primary key,addr text);";
>
>sql="insert into em values(44,21);"\
>    "insert into em values(11,20);"\
>"insert into em values(5,20);"\
>    "insert into idv values(11,44);"\
>    "insert into idv values(5,11);"\
>"insert into idv values(44,180);"\
>    "insert into mny values(5,10000);"\
>    "insert into mny values(11,5000);"\
>"insert into mny values(44,5000);"\
>    "insert into lo values(5,'NY');"\
>    "insert into lo values(44,'che');"\
>"insert into lo values(11,'NY');";
>
>sql="select * from em,lo,mny,idv where lo.name=em.name and idv.id=mny.id
>";
>
>VDBE:
>
>   0 Init             0   41    0               00
>   1 OpenRead         0    2    0 2             00
>   2 OpenRead         1    9    0 2             00
>   3 OpenRead         4   10    0 k(2,nil,nil)  00
>   4 OpenRead         2    7    0 2             00
>   5 OpenRead         3    5    0 2             00
>   6 OpenRead         5    6    0 k(2,nil,nil)  00
>   7 Rewind           0   34    0               00
>   8 Column           0    0    1               00
>   9 IsNull           1   33    0               00
>  10 Affinity         1    1    0 D             00
>  11 SeekGE           4   33    1 1             00
>  12 IdxGT            4   33    1 1             00
>  13 IdxRowid         4    2    0               00
>  14 Seek             1    2    0               00
>  15 Rewind           2   33    0               00
>  16 Column           2    0    3               00
>  17 IsNull           3   32    0               00
>  18 Affinity         3    1    0 D             00
>  19 SeekGE           5   32    3 1             00
>  20 IdxGT            5   32    3 1             00
>  21 IdxRowid         5    4    0               00
>  22 Seek             3    4    0               00
>  23 Column           0    0    5               00
>  24 Column           0    1    6               00
>  25 Column           4    0    7               00
>  26 Column           1    1    8               00
>  27 Column           2    0    9               00
>  28 Column           2    1   10               00
>  29 Column           5    0   11               00
>  30 Column           3    1   12               00
>  31 ResultRow        5    8    0               00
>  32 Next             2   16    0               01
>  33 Next             0    8    0               01
>  34 Close            0    0    0               00
>  35 Close            1    0    0               00
>  36 Close            4    0    0               00
>  37 Close            2    0    0               00
>  38 Close            3    0    0               00
>  39 Close            5    0    0               00
>  40 Halt             0    0    0               00
>  41 Transaction      0    0 44729 0             01
>  42 TableLock        0    2    0 em            00
>  43 TableLock        0    9    0 lo            00
>  44 TableLock        0    7    0 mny           00
>  45 TableLock        0    5    0 idv           00
>  46 Goto             0    1    0               00
>
>
>How sqlite works in this case ?
>because there are 4 tables and for only 2 tables(or indices) it opened
>loops ?
>The next opcodes belongs to which tables in this case?
>
>
>On Tue, Mar 17, 2015 at 5:47 PM, Hick Gunter <hick at scigames.at> wrote:
>
>> If there can be not more than one row that satisfies the constraints
>(i.e.
>> the constraints specifiy a unique key) and there is an index (express
>or
>> implied or autocreated) available, then a simple index lookup will
>suffice.
>>
>> How many rows do you expect to have a rowid of 1?
>> How many rows do you expect to read from table a for each row of table
>b
>> if a_rowid is a foreign key?
>>
>> create temp table a (f1 integer);
>> create temp table b (a_rowid integer, f2 integer);
>>
>> .explain
>> explain select * from a where rowid = 1;
>> addr  opcode         p1    p2    p3    p4             p5  comment
>> ----  -------------  ----  ----  ----  -------------  --  -------------
>> 0     Trace          0     0     0                    00  NULL
>> 1     Integer        1     1     0                    00  NULL
>> 2     Goto           0     10    0                    00  NULL
>> 3     OpenRead       0     2     1     1              00  a
>> 4     MustBeInt      1     8     0                    00  NULL
>> 5     NotExists      0     8     1                    00  pk
>> 6     Column         0     0     3                    00  a.f1
>> 7     ResultRow      3     1     0                    00  NULL
>> 8     Close          0     0     0                    00  NULL
>> 9     Halt           0     0     0                    00  NULL
>> 10    Transaction    1     0     0                    00  NULL
>> 11    VerifyCookie   1     1     0                    00  NULL
>> 12    TableLock      1     2     0     a              00  NULL
>> 13    Goto           0     3     0                    00  NULL
>>
>> explain select * from a join b on a.rowid=b.a_rowid where b.f2 = 1;
>> addr  opcode         p1    p2    p3    p4             p5  comment
>> ----  -------------  ----  ----  ----  -------------  --  -------------
>> 0     Trace          0     0     0                    00  NULL
>> 1     Integer        1     1     0                    00  NULL
>> 2     Goto           0     19    0                    00  NULL
>> 3     OpenRead       1     3     1     2              00  b
>> 4     OpenRead       0     2     1     1              00  a
>> 5     Rewind         1     16    0                    00  NULL
>> 6     Column         1     1     2                    00  b.f2
>> 7     Ne             1     15    2     collseq(BINARY)  6c  NULL
>> 8     Column         1     0     3                    00  b.a_rowid
>> 9     MustBeInt      3     15    0                    00  NULL
>> 10    NotExists      0     15    3                    00  pk
>> 11    Column         0     0     4                    00  a.f1
>> 12    Column         1     0     5                    00  b.a_rowid
>> 13    Column         1     1     6                    00  b.f2
>> 14    ResultRow      4     3     0                    00  NULL
>> 15    Next           1     6     0                    01  NULL
>> 16    Close          1     0     0                    00  NULL
>> 17    Close          0     0     0                    00  NULL
>> 18    Halt           0     0     0                    00  NULL
>> 19    Transaction    1     0     0                    00  NULL
>> 20    VerifyCookie   1     2     0                    00  NULL
>> 21    TableLock      1     3     0     b              00  NULL
>> 22    TableLock      1     2     0     a              00  NULL
>> 23    Goto           0     3     0                    00  NULL
>>
>> -----Urspr?ngliche Nachricht-----
>> Von: Sairam Gaddam [mailto:gaddamsairam at gmail.com]
>> Gesendet: Dienstag, 17. M?rz 2015 12:26
>> An: General Discussion of SQLite Database
>> Betreff: [sqlite] regarding loops in vdbe code
>>
>> When joining a table in sqlite with some condition using where clause,
>> sqlite sometimes generate less number of loops(Next opcodes) than the
>> number of tables.
>> Can anyone explain how sqlite iterates through all the tables when it
>has
>> less number of loops.
>> _______________________________________________
>> sqlite-users mailing list
>> sqlite-users at mailinglists.sqlite.org
>> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
>>
>>
>> ___________________________________________
>>  Gunter Hick
>> Software Engineer
>> Scientific Games International GmbH
>> FN 157284 a, HG Wien
>> Klitschgasse 2-4, A-1130 Vienna, Austria
>> Tel: +43 1 80100 0
>> E-Mail: hick at scigames.at
>>
>> This communication (including any attachments) is intended for the use
>of
>> the intended recipient(s) only and may contain information that is
>> confidential, privileged or legally protected. Any unauthorized use or
>> dissemination of this communication is strictly prohibited. If you have
>> received this communication in error, please immediately notify the
>sender
>> by return e-mail message and delete all copies of the original
>> communication. Thank you for your cooperation.
>>
>>
>> _______________________________________________
>> sqlite-users mailing list
>> sqlite-users at mailinglists.sqlite.org
>> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
>>
>_______________________________________________
>sqlite-users mailing list
>sqlite-users at mailinglists.sqlite.org
>http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users



Reply via email to