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