Hi,

After I updated sqlite with 3.11 to 3.12, I noticed that several 
requests to the virtual tables have become much slower.
I was able to replicate the problem on conventional tables.

--Make tables

DROP TABLE IF EXISTS test;
CREATE TABLE test(id,val);
INSERT INTO test
     WITH RECURSIVE
       cte(id,val) AS (
       VALUES(1 , random()%1000) UNION ALL
       SELECT id+1,random()%1000 FROM cte WHERE ID<10000000)
     select * from cte;
CREATE INDEX idx_id ON test(id);
CREATE INDEX idx_val ON test(val);

DROP TABLE IF EXISTS sel;
CREATE TABLE sel(val);
INSERT INTO sel
     WITH RECURSIVE
       cte(id) AS (
       VALUES(1) UNION ALL
       SELECT id+1 FROM cte WHERE ID<1000)
     select * from cte;

ANALYZE;

-- query with index idx_val
explain SELECT count(*) FROM test WHERE id BETWEEN 10000 AND 2000000 AND 
val IN (SELECT val from sel);
SELECT count(*) FROM test WHERE id BETWEEN 10000 AND 2000000 AND val IN 
(SELECT val from sel);

addr  opcode         p1    p2    p3    p4             p5  comment
----  -------------  ----  ----  ----  -------------  --  -------------
0     Init           0     31    0                    00  Start at 31
1     Null           0     1     1                    00  r[1..1]=NULL
2     OpenRead       0     8     0     2              00  root=8 iDb=0; 
test
3     OpenRead       2     67443  0     k(2,,)         02  root=67443 
iDb=0; idx_val
4     Once           0     13    0                    00
5     OpenEphemeral  4     1     0     k(1,B)         00  nColumn=1
6     OpenRead       1     2     0     1              00  root=2 iDb=0; sel
7     Rewind         1     12    0                    00
8       Column         1     0     3                    00  r[3]=sel.val
9       MakeRecord     3     1     4     A              00 
  r[4]=mkrec(r[3])
10      IdxInsert      4     4     0                    00  key=r[4]
11    Next           1     8     0                    01
12    Close          1     0     0                    00
13    Rewind         4     25    0                    00
14      Column         4     0     2                    00  r[2]=
15      IsNull         2     24    0                    00  if 
r[2]==NULL goto 24
16      SeekGE         2     24    2     1              00  key=r[2]
17        IdxGT          2     24    2     1              00  key=r[2]
18        Seek           2     0     0                    00  Move 0 to 
2.rowid
19        Column         0     0     4                    00  r[4]=test.id
20        Lt             6     23    4     (BINARY)       51  if 
r[6]<r[4] goto 23
21        Gt             7     23    4     (BINARY)       51  if 
r[7]>r[4] goto 23
22        AggStep0       0     0     1     count(0)       00  accum=r[1] 
step(r[0])
23      Next           2     17    0                    00
24    NextIfOpen     4     14    0                    00
25    Close          0     0     0                    00
26    Close          2     0     0                    00
27    AggFinal       1     0     0     count(0)       00  accum=r[1] N=0
28    Copy           1     8     0                    00  r[8]=r[1]
29    ResultRow      8     1     0                    00  output=r[8]
30    Halt           0     0     0                    00
31    Transaction    0     0     393   0              01  usesStmtJournal=0
32    TableLock      0     8     0     test           00  iDb=0 root=8 
write=0
33    TableLock      0     2     0     sel            00  iDb=0 root=2 
write=0
34    Integer        10000  6     0                    00  r[6]=10000
35    Integer        2000000  7     0                    00  r[7]=2000000
36    Goto           0     1     0                    00
Run Time: real 0.147 user 0.000000 sys 0.000000
994089
Run Time: real 29.520 user 5.781250 sys 22.703125

-- query without index idx_val
explain SELECT count(*) FROM test WHERE id BETWEEN 10000 AND 2000000 AND 
+val IN (SELECT val from sel);
SELECT count(*) FROM test WHERE id BETWEEN 10000 AND 2000000 AND +val IN 
(SELECT val from sel);

addr  opcode         p1    p2    p3    p4             p5  comment
----  -------------  ----  ----  ----  -------------  --  -------------
0     Init           0     31    0                    00  Start at 31
1     Null           0     1     1                    00  r[1..1]=NULL
2     OpenRead       0     8     0     2              00  root=8 iDb=0; 
test
3     OpenRead       2     9     0     k(2,,)         00  root=9 iDb=0; 
idx_id
4     Integer        10000  2     0                    00  r[2]=10000
5     SeekGE         2     25    2     1              00  key=r[2]
6     Integer        2000000  2     0                    00  r[2]=2000000
7       IdxGT          2     25    2     1              00  key=r[2]
8       Seek           2     0     0                    00  Move 0 to 
2.rowid
9       Noop           0     0     0                    00  begin IN expr
10      Once           0     19    0                    00
11      OpenEphemeral  4     1     0     k(1,B)         00  nColumn=1
12      OpenRead       1     2     0     1              00  root=2 
iDb=0; sel
13      Rewind         1     18    0                    00
14        Column         1     0     3                    00  r[3]=sel.val
15        MakeRecord     3     1     4     A              00 
  r[4]=mkrec(r[3])
16        IdxInsert      4     4     0                    00  key=r[4]
17      Next           1     14    0                    01
18      Close          1     0     0                    00
19      Column         0     1     4                    00  r[4]=test.val
20      IsNull         4     24    0                    00  if 
r[4]==NULL goto 24
21      Affinity       4     1     0     A              00  affinity(r[4])
22      NotFound       4     24    4     1              00  key=r[4]; 
end IN expr
23      AggStep0       0     0     1     count(0)       00  accum=r[1] 
step(r[0])
24    Next           2     7     0                    00
25    Close          0     0     0                    00
26    Close          2     0     0                    00
27    AggFinal       1     0     0     count(0)       00  accum=r[1] N=0
28    Copy           1     5     0                    00  r[5]=r[1]
29    ResultRow      5     1     0                    00  output=r[5]
30    Halt           0     0     0                    00
31    Transaction    0     0     393   0              01  usesStmtJournal=0
32    TableLock      0     8     0     test           00  iDb=0 root=8 
write=0
33    TableLock      0     2     0     sel            00  iDb=0 root=2 
write=0
34    Goto           0     1     0                    00
Run Time: real 0.138 user 0.015625 sys 0.000000
994089
Run Time: real 1.868 user 1.656250 sys 0.140625

I guess that aggressiveness in optimization is too high and its priority 
should be somehow reduced.



---
??? ????????? ????????? ?? ?????? ??????????? Avast.
https://www.avast.com/antivirus

Reply via email to