mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-12 13:01:09 +03:00
Improve the way that skip-scan loops are constructued. Add test cases.
Improved the scoring of skip-scan loops. FossilOrigin-Name: 5e75ab93881b85801cb4ebf70f2063ff7c51ac19
This commit is contained in:
16
manifest
16
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Add\stest\scases\sfor\sskip-scan.\s\sEnhance\s"do_test"\sso\sthat\sif\sthe\sexpected\sresult\nis\sof\sthe\sform\s"/*..*/"\sor\s"~/*..*/"\sit\streats\sthe\sexpected\sresult\sas\sa\sglob\npattern\srather\sthan\sas\sa\sregular\sexpression.\s\sFix\sa\sbug\sin\sANALYZE\sresult\nloading\sassociated\swith\sWITHOUT\sROWID\stables.
|
C Improve\sthe\sway\sthat\sskip-scan\sloops\sare\sconstructued.\s\sAdd\stest\scases.\nImproved\sthe\sscoring\sof\sskip-scan\sloops.
|
||||||
D 2013-11-13T15:32:15.331
|
D 2013-11-13T16:58:54.547
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1
|
F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@@ -293,8 +293,8 @@ F src/vtab.c 5a423b042eb1402ef77697d03d6a67378d97bc8d
|
|||||||
F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4
|
F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4
|
||||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||||
F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74
|
F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74
|
||||||
F src/where.c 15170b152697e8819de5909031d72ad52a28a7ef
|
F src/where.c f50428d2e93ca3e5c541cc1c2084833b48db947c
|
||||||
F src/whereInt.h a0e8fa5364122c6cb27c6fa340b257a05c592bfb
|
F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358
|
||||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||||
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
|
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
|
||||||
@@ -805,7 +805,7 @@ F test/shell5.test 46c8c18d62732415c4fe084816c13d559831705e
|
|||||||
F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
|
F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
|
||||||
F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868
|
F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868
|
||||||
F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329
|
F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329
|
||||||
F test/skipscan1.test 63af32c300be545417410ea2ce44e78c5b2e34b1
|
F test/skipscan1.test bc65ecb228eba396c404aa038f49798340f0677f
|
||||||
F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f
|
F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f
|
||||||
F test/softheap1.test 40562fe6cac6d9827b7b42b86d45aedf12c15e24
|
F test/softheap1.test 40562fe6cac6d9827b7b42b86d45aedf12c15e24
|
||||||
F test/sort.test 0e4456e729e5a92a625907c63dcdedfbe72c5dc5
|
F test/sort.test 0e4456e729e5a92a625907c63dcdedfbe72c5dc5
|
||||||
@@ -1139,7 +1139,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
|
|||||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||||
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
|
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
|
||||||
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
|
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
|
||||||
P 27dd5993d1ae5625eb94bf406421eb390d001be9
|
P d3e6e9b2a74074c05429d3c341c23525504351ab
|
||||||
R 56958c69a5559324c31384471b37b6dc
|
R 2b49a424145c7566c72f185654c1a259
|
||||||
U drh
|
U drh
|
||||||
Z 2ff45f7229fb8bf180b3b10c0362f0e0
|
Z 03bb67f899f79fcc8cd9bd00c60852e3
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
d3e6e9b2a74074c05429d3c341c23525504351ab
|
5e75ab93881b85801cb4ebf70f2063ff7c51ac19
|
||||||
28
src/where.c
28
src/where.c
@@ -2504,11 +2504,11 @@ static int codeAllEqualityTerms(
|
|||||||
|
|
||||||
if( nSkip ){
|
if( nSkip ){
|
||||||
int iIdxCur = pLevel->iIdxCur;
|
int iIdxCur = pLevel->iIdxCur;
|
||||||
sqlite3VdbeAddOp2(v, (bRev?OP_Last:OP_Rewind), iIdxCur, pLevel->addrNxt);
|
sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur);
|
||||||
pLevel->addrSkip = sqlite3VdbeCurrentAddr(v);
|
j = sqlite3VdbeAddOp0(v, OP_Goto);
|
||||||
pLevel->opSkip = bRev ? OP_SeekLt : OP_SeekGt;
|
pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLt:OP_SeekGt),
|
||||||
pLevel->p3Skip = regBase;
|
iIdxCur, 0, regBase, nSkip);
|
||||||
pLevel->p4Skip = nSkip;
|
sqlite3VdbeJumpHere(v, j);
|
||||||
for(j=0; j<nSkip; j++){
|
for(j=0; j<nSkip; j++){
|
||||||
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, j, regBase+j);
|
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, j, regBase+j);
|
||||||
assert( pIdx->aiColumn[j]>=0 );
|
assert( pIdx->aiColumn[j]>=0 );
|
||||||
@@ -3928,11 +3928,13 @@ static int whereLoopAddBtreeIndex(
|
|||||||
&& saved_nEq+1<pProbe->nKeyCol
|
&& saved_nEq+1<pProbe->nKeyCol
|
||||||
&& pProbe->aiRowEst[saved_nEq+1]>50
|
&& pProbe->aiRowEst[saved_nEq+1]>50
|
||||||
){
|
){
|
||||||
|
LogEst nIter;
|
||||||
pNew->u.btree.nEq++;
|
pNew->u.btree.nEq++;
|
||||||
pNew->u.btree.nSkip++;
|
pNew->u.btree.nSkip++;
|
||||||
pNew->aLTerm[pNew->nLTerm++] = 0;
|
pNew->aLTerm[pNew->nLTerm++] = 0;
|
||||||
pNew->wsFlags |= WHERE_SKIP_SCAN;
|
pNew->wsFlags |= WHERE_SKIPSCAN;
|
||||||
whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul);
|
nIter = sqlite3LogEst(pProbe->aiRowEst[0]/pProbe->aiRowEst[saved_nEq+1]);
|
||||||
|
whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter);
|
||||||
}
|
}
|
||||||
for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){
|
for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){
|
||||||
int nIn = 0;
|
int nIn = 0;
|
||||||
@@ -3969,8 +3971,10 @@ static int whereLoopAddBtreeIndex(
|
|||||||
pNew->u.btree.nEq++;
|
pNew->u.btree.nEq++;
|
||||||
pNew->nOut = nRowEst + nInMul + nIn;
|
pNew->nOut = nRowEst + nInMul + nIn;
|
||||||
}else if( pTerm->eOperator & (WO_EQ) ){
|
}else if( pTerm->eOperator & (WO_EQ) ){
|
||||||
assert( (pNew->wsFlags & (WHERE_COLUMN_NULL|WHERE_COLUMN_IN))!=0
|
assert(
|
||||||
|| nInMul==0 );
|
(pNew->wsFlags & (WHERE_COLUMN_NULL|WHERE_COLUMN_IN|WHERE_SKIPSCAN))!=0
|
||||||
|
|| nInMul==0
|
||||||
|
);
|
||||||
pNew->wsFlags |= WHERE_COLUMN_EQ;
|
pNew->wsFlags |= WHERE_COLUMN_EQ;
|
||||||
if( iCol<0
|
if( iCol<0
|
||||||
|| (pProbe->onError!=OE_None && nInMul==0
|
|| (pProbe->onError!=OE_None && nInMul==0
|
||||||
@@ -5784,11 +5788,9 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
|
|||||||
}
|
}
|
||||||
sqlite3VdbeResolveLabel(v, pLevel->addrBrk);
|
sqlite3VdbeResolveLabel(v, pLevel->addrBrk);
|
||||||
if( pLevel->addrSkip ){
|
if( pLevel->addrSkip ){
|
||||||
addr = sqlite3VdbeAddOp4Int(v, pLevel->opSkip, pLevel->iIdxCur, 0,
|
|
||||||
pLevel->p3Skip, pLevel->p4Skip);
|
|
||||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrSkip);
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrSkip);
|
||||||
sqlite3VdbeJumpHere(v, pLevel->addrSkip-1);
|
sqlite3VdbeJumpHere(v, pLevel->addrSkip);
|
||||||
sqlite3VdbeJumpHere(v, addr);
|
sqlite3VdbeJumpHere(v, pLevel->addrSkip-2);
|
||||||
}
|
}
|
||||||
if( pLevel->iLeftJoin ){
|
if( pLevel->iLeftJoin ){
|
||||||
addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin);
|
addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin);
|
||||||
|
|||||||
@@ -71,10 +71,7 @@ struct WhereLevel {
|
|||||||
int addrBody; /* Beginning of the body of this loop */
|
int addrBody; /* Beginning of the body of this loop */
|
||||||
u8 iFrom; /* Which entry in the FROM clause */
|
u8 iFrom; /* Which entry in the FROM clause */
|
||||||
u8 op, p5; /* Opcode and P5 of the opcode that ends the loop */
|
u8 op, p5; /* Opcode and P5 of the opcode that ends the loop */
|
||||||
u8 opSkip; /* Opcode to terminate the skip-scan */
|
|
||||||
int p1, p2; /* Operands of the opcode used to ends the loop */
|
int p1, p2; /* Operands of the opcode used to ends the loop */
|
||||||
int p3Skip; /* P3 operand for the skip-scan terminator */
|
|
||||||
u16 p4Skip; /* P4 operand for the skip-scan terminator */
|
|
||||||
union { /* Information that depends on pWLoop->wsFlags */
|
union { /* Information that depends on pWLoop->wsFlags */
|
||||||
struct {
|
struct {
|
||||||
int nIn; /* Number of entries in aInLoop[] */
|
int nIn; /* Number of entries in aInLoop[] */
|
||||||
@@ -459,4 +456,4 @@ struct WhereInfo {
|
|||||||
#define WHERE_ONEROW 0x00001000 /* Selects no more than one row */
|
#define WHERE_ONEROW 0x00001000 /* Selects no more than one row */
|
||||||
#define WHERE_MULTI_OR 0x00002000 /* OR using multiple indices */
|
#define WHERE_MULTI_OR 0x00002000 /* OR using multiple indices */
|
||||||
#define WHERE_AUTO_INDEX 0x00004000 /* Uses an ephemeral index */
|
#define WHERE_AUTO_INDEX 0x00004000 /* Uses an ephemeral index */
|
||||||
#define WHERE_SKIP_SCAN 0x00008000 /* Uses the skip-scan algorithm */
|
#define WHERE_SKIPSCAN 0x00008000 /* Uses the skip-scan algorithm */
|
||||||
|
|||||||
@@ -74,22 +74,49 @@ do_execsql_test skipscan1-1.4sort {
|
|||||||
SELECT a,b,c,d,'|' FROM t1 WHERE c=6 ORDER BY a, b, c;
|
SELECT a,b,c,d,'|' FROM t1 WHERE c=6 ORDER BY a, b, c;
|
||||||
} {~/*ORDER BY*/}
|
} {~/*ORDER BY*/}
|
||||||
|
|
||||||
|
do_execsql_test skipscan1-1.5 {
|
||||||
|
SELECT a,b,c,d,'|' FROM t1 WHERE c IN (6,7) ORDER BY a, b, c;
|
||||||
|
} {abc 234 6 7 | abc 345 7 8 | bcd 100 6 11 |}
|
||||||
|
do_execsql_test skipscan1-1.5eqp {
|
||||||
|
EXPLAIN QUERY PLAN
|
||||||
|
SELECT a,b,c,d,'|' FROM t1 WHERE c IN (6,7) ORDER BY a, b, c;
|
||||||
|
} {/* USING INDEX t1abc (ANY(a) AND ANY(b) AND c=?)*/}
|
||||||
|
do_execsql_test skipscan1-1.5sort {
|
||||||
|
EXPLAIN QUERY PLAN
|
||||||
|
SELECT a,b,c,d,'|' FROM t1 WHERE c IN (6,7) ORDER BY a, b, c;
|
||||||
|
} {~/*ORDER BY*/}
|
||||||
|
|
||||||
|
do_execsql_test skipscan1-1.6 {
|
||||||
|
SELECT a,b,c,d,'|' FROM t1 WHERE c BETWEEN 6 AND 7 ORDER BY a, b, c;
|
||||||
|
} {abc 234 6 7 | abc 345 7 8 | bcd 100 6 11 |}
|
||||||
|
do_execsql_test skipscan1-1.6eqp {
|
||||||
|
EXPLAIN QUERY PLAN
|
||||||
|
SELECT a,b,c,d,'|' FROM t1 WHERE c BETWEEN 6 AND 7 ORDER BY a, b, c;
|
||||||
|
} {/* USING INDEX t1abc (ANY(a) AND ANY(b) AND c>? AND c<?)*/}
|
||||||
|
do_execsql_test skipscan1-1.6sort {
|
||||||
|
EXPLAIN QUERY PLAN
|
||||||
|
SELECT a,b,c,d,'|' FROM t1 WHERE c BETWEEN 6 AND 7 ORDER BY a, b, c;
|
||||||
|
} {~/*ORDER BY*/}
|
||||||
|
|
||||||
|
|
||||||
# Joins
|
# Joins
|
||||||
#
|
#
|
||||||
do_execsql_test skipscan1-1.5 {
|
do_execsql_test skipscan1-1.51 {
|
||||||
CREATE TABLE t1j(x TEXT, y INTEGER);
|
CREATE TABLE t1j(x TEXT, y INTEGER);
|
||||||
INSERT INTO t1j VALUES('one',1),('six',6),('ninty-nine',99);
|
INSERT INTO t1j VALUES('one',1),('six',6),('ninty-nine',99);
|
||||||
|
INSERT INTO sqlite_stat1 VALUES('t1j',null,'3');
|
||||||
|
ANALYZE sqlite_master;
|
||||||
SELECT x, a, b, c, d, '|' FROM t1j, t1 WHERE c=y ORDER BY +a;
|
SELECT x, a, b, c, d, '|' FROM t1j, t1 WHERE c=y ORDER BY +a;
|
||||||
} {six abc 234 6 7 | six bcd 100 6 11 |}
|
} {six abc 234 6 7 | six bcd 100 6 11 |}
|
||||||
do_execsql_test skipscan1-1.5eqp {
|
do_execsql_test skipscan1-1.51eqp {
|
||||||
EXPLAIN QUERY PLAN
|
EXPLAIN QUERY PLAN
|
||||||
SELECT x, a, b, c, d, '|' FROM t1j, t1 WHERE c=y ORDER BY +a;
|
SELECT x, a, b, c, d, '|' FROM t1j, t1 WHERE c=y ORDER BY +a;
|
||||||
} {/* INDEX t1abc (ANY(a) AND ANY(b) AND c=?)*/}
|
} {/* INDEX t1abc (ANY(a) AND ANY(b) AND c=?)*/}
|
||||||
|
|
||||||
do_execsql_test skipscan1-1.6 {
|
do_execsql_test skipscan1-1.52 {
|
||||||
SELECT x, a, b, c, d, '|' FROM t1j LEFT JOIN t1 ON c=y ORDER BY +y, +a;
|
SELECT x, a, b, c, d, '|' FROM t1j LEFT JOIN t1 ON c=y ORDER BY +y, +a;
|
||||||
} {one {} {} {} {} | six abc 234 6 7 | six bcd 100 6 11 | ninty-nine {} {} {} {} |}
|
} {one {} {} {} {} | six abc 234 6 7 | six bcd 100 6 11 | ninty-nine {} {} {} {} |}
|
||||||
do_execsql_test skipscan1-1.6eqp {
|
do_execsql_test skipscan1-1.52eqp {
|
||||||
EXPLAIN QUERY PLAN
|
EXPLAIN QUERY PLAN
|
||||||
SELECT x, a, b, c, d, '|' FROM t1j LEFT JOIN t1 ON c=y ORDER BY +y, +a;
|
SELECT x, a, b, c, d, '|' FROM t1j LEFT JOIN t1 ON c=y ORDER BY +y, +a;
|
||||||
} {/* INDEX t1abc (ANY(a) AND ANY(b) AND c=?)*/}
|
} {/* INDEX t1abc (ANY(a) AND ANY(b) AND c=?)*/}
|
||||||
|
|||||||
Reference in New Issue
Block a user