> Paul wrote:
> > I've traced this issue down to the simplest test case:
> >
> > CREATE TABLE IF NOT EXISTS foo
> > (
> >  id  INTEGER,
> >  baz INTEGER,
> >  PRIMARY KEY(id)
> > );
> >
> > CREATE INDEX IF NOT EXISTS baz_foo_idx ON foo(baz, id);
> >
> > CREATE TABLE IF NOT EXISTS bar
> > (
> >  foo INTEGER,
> >  PRIMARY KEY(foo),
> >  FOREIGN KEY(foo) REFERENCES foo(id) ON DELETE CASCADE
> > );
> >
> > WITH RECURSIVE
> >  cnt(x, y) AS (VALUES(1, 1) UNION ALL SELECT x + 1, x + 1 FROM cnt WHERE x 
> > < 200000)
> >  INSERT INTO foo(id, baz) SELECT x, y FROM cnt;
> >
> > WITH RECURSIVE
> >  cnt(x) AS (VALUES(1) UNION ALL SELECT x + 3 FROM cnt WHERE x < 50000)
> >  INSERT INTO bar SELECT x FROM cnt;
> >
> > This query takes too much time:
> >
> >  SELECT id FROM foo WHERE baz = 10000 AND id IN (SELECT foo FROM bar) LIMIT 
> > 1;
> 
> EXPLAIN SELECT id FROM foo WHERE baz = 10000 AND id IN (SELECT foo FROM bar) 
> LIMIT 1;
> addr  opcode         p1    p2    p3    p4             p5  comment
> ----  -------------  ----  ----  ----  -------------  --  -------------
> 0     Init           0     24    0                    00  Start at 24
> 1     Integer        1     1     0                    00  r[1]=1; LIMIT 
> counter
> 2     OpenRead       2     3     0     k(3,,,)        02  root=3 iDb=0; 
> baz_foo_idx
> 3     Integer        10000  2     0                    00  r[2]=10000
> 4     Once           0     6     0                    00
> 5     OpenRead       3     4     0     1              00  root=4 iDb=0; bar
> 6     Rewind         3     22    0                    00
> 7       Rowid          3     3     0                    00  r[3]=rowid
> 8       IsNull         3     21    0                    00  if r[3]==NULL 
> goto 21
> 9       Once           1     11    0                    00
> 10      OpenRead       4     4     0     1              00  root=4 iDb=0; bar
> 11      Rewind         4     21    0                    00
> 12        Rowid          4     4     0                    00  r[4]=rowid
> 13        IsNull         4     20    0                    00  if r[4]==NULL 
> goto 20
> 14        SeekGE         2     20    2     3              00  key=r[2..4]
> 15          IdxGT          2     20    2     3              00  key=r[2..4]
> 16          IdxRowid       2     5     0                    00  r[5]=rowid
> 17          ResultRow      5     1     0                    00  output=r[5]
> 18          DecrJumpZero   1     22    0                    00  if 
> (--r[1])==0 goto 22
> 19        Next           2     15    0                    00
> 20      NextIfOpen     4     12    0                    00
> 21    NextIfOpen     3     7     0                    00
> 22    Close          2     0     0                    00
> 23    Halt           0     0     0                    00
> 24    Transaction    0     0     3     0              01  usesStmtJournal=0
> 25    TableLock      0     2     0     foo            00  iDb=0 root=2 write=0
> 26    TableLock      0     4     0     bar            00  iDb=0 root=4 write=0
> 27    Goto           0     1     0                    00
> 
> If I've understood this correctly, it's the equivalent of this pseudocode:
> 
>   cursor c3 = scan bar
>   for each row in c3:
>       cursor c4 = scan bar
>       for each row in c4:
>           cursor c2 = search (10000, c3.rowid, c4.rowid) in baz_foo_idx
>           for each row in c2:
>               output c2.rowid
>               stop
> 
> This looks like a bug.
> 
> As a workaround, drop "id" from the index (the rowid is always part of
> the index anyway).

Thank you for the information! 

We'll stick with the old version for now, until the bug is fixed, since it's 
hard to change database structure since there are millions of copies. Also we 
use 'ORDER BY baz DESC, id DESC' and I'm not sure how will it work out in case 
of index on the single baz field.
 
 
_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to