Enhancements to skip-scan such that it is operable when a middle column of
an index is skipped while the left-most column is constrained in the WHERE clause. FossilOrigin-Name: bc985caa7816f1f873ad8e4467c5278399f315ce
This commit is contained in:
parent
7bc4c454da
commit
f3f69ac942
13
manifest
13
manifest
@ -1,5 +1,5 @@
|
||||
C A\ssmall\sperformance\simprovement\sin\sfreeSpace()\sby\sspecial-casing\sthe\nrelatively\scommon\scase\sof\san\sempty\sfreelist.
|
||||
D 2014-08-20T18:43:44.510
|
||||
C Enhancements\sto\sskip-scan\ssuch\sthat\sit\sis\soperable\swhen\sa\smiddle\scolumn\sof\nan\sindex\sis\sskipped\swhile\sthe\sleft-most\scolumn\sis\sconstrained\sin\sthe\sWHERE\nclause.
|
||||
D 2014-08-20T23:38:07.310
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 5eb79e334a5de69c87740edd56af6527dd219308
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@ -296,7 +296,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd
|
||||
F src/wal.c 264df50a1b33124130b23180ded2e2c5663c652a
|
||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||
F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45
|
||||
F src/where.c ab20f9c24a422ee8900831b343c3d1e5e7aca87b
|
||||
F src/where.c 4c499d185827a492643cf017ae5e3aa0523f9f18
|
||||
F src/whereInt.h 923820bee9726033a501a08d2fc69b9c1ee4feb3
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
@ -832,6 +832,7 @@ F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868
|
||||
F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329
|
||||
F test/skipscan1.test 28c7faa41a0d7265040ecb0a0abd90c0904270b2
|
||||
F test/skipscan2.test d1d1450952b7275f0b0a3a981f0230532743951a
|
||||
F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5
|
||||
F test/skipscan5.test d8b9692b702745a0e41c23f9da6beac81df01196
|
||||
F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f
|
||||
F test/softheap1.test 40562fe6cac6d9827b7b42b86d45aedf12c15e24
|
||||
@ -1186,7 +1187,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P fe4fd014b42b7b158ca968f1535b5636c67769f6
|
||||
R 865eceb09aea170bb70d44b771b85e6e
|
||||
P 49f44d355ff70744e4951baca2481c7c2b6c02b3
|
||||
R 96923099996337b045b25027695cfca6
|
||||
U drh
|
||||
Z 0631afdcc5729e41fc50a75336710200
|
||||
Z 1b9938878e462b798940573e6153541a
|
||||
|
@ -1 +1 @@
|
||||
49f44d355ff70744e4951baca2481c7c2b6c02b3
|
||||
bc985caa7816f1f873ad8e4467c5278399f315ce
|
21
src/where.c
21
src/where.c
@ -3781,8 +3781,8 @@ static void whereLoopPrint(WhereLoop *p, WhereClause *pWC){
|
||||
sqlite3DebugPrintf(" %12s",
|
||||
pItem->zAlias ? pItem->zAlias : pTab->zName);
|
||||
if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
|
||||
const char *zName;
|
||||
if( p->u.btree.pIndex && (zName = p->u.btree.pIndex->zName)!=0 ){
|
||||
const char *zName;
|
||||
if( p->u.btree.pIndex && (zName = p->u.btree.pIndex->zName)!=0 ){
|
||||
if( strncmp(zName, "sqlite_autoindex_", 17)==0 ){
|
||||
int i = sqlite3Strlen30(zName) - 1;
|
||||
while( zName[i]!='_' ) i--;
|
||||
@ -3803,7 +3803,11 @@ static void whereLoopPrint(WhereLoop *p, WhereClause *pWC){
|
||||
sqlite3DebugPrintf(" %-19s", z);
|
||||
sqlite3_free(z);
|
||||
}
|
||||
sqlite3DebugPrintf(" f %05x N %d", p->wsFlags, p->nLTerm);
|
||||
if( p->wsFlags & WHERE_SKIPSCAN ){
|
||||
sqlite3DebugPrintf(" f %05x %d-%d", p->wsFlags, p->nLTerm,p->u.btree.nSkip);
|
||||
}else{
|
||||
sqlite3DebugPrintf(" f %05x N %d", p->wsFlags, p->nLTerm);
|
||||
}
|
||||
sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut);
|
||||
#ifdef SQLITE_ENABLE_TREE_EXPLAIN
|
||||
/* If the 0x100 bit of wheretracing is set, then show all of the constraint
|
||||
@ -4316,8 +4320,7 @@ static int whereLoopAddBtreeIndex(
|
||||
** On the other hand, the extra seeks could end up being significantly
|
||||
** more expensive. */
|
||||
assert( 42==sqlite3LogEst(18) );
|
||||
if( pTerm==0
|
||||
&& saved_nEq==saved_nSkip
|
||||
if( saved_nEq==saved_nSkip
|
||||
&& saved_nEq+1<pProbe->nKeyCol
|
||||
&& pProbe->aiRowLogEst[saved_nEq+1]>=42 /* TUNING: Minimum for skip-scan */
|
||||
&& (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK
|
||||
@ -4328,9 +4331,17 @@ static int whereLoopAddBtreeIndex(
|
||||
pNew->aLTerm[pNew->nLTerm++] = 0;
|
||||
pNew->wsFlags |= WHERE_SKIPSCAN;
|
||||
nIter = pProbe->aiRowLogEst[saved_nEq] - pProbe->aiRowLogEst[saved_nEq+1];
|
||||
if( pTerm ){
|
||||
/* TUNING: When estimating skip-scan for a term that is also indexable,
|
||||
** increase the cost of the skip-scan by 2x, to make it a little less
|
||||
** desirable than the regular index lookup. */
|
||||
nIter += 10; assert( 10==sqlite3LogEst(2) );
|
||||
}
|
||||
pNew->nOut -= nIter;
|
||||
whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter + nInMul);
|
||||
pNew->nOut = saved_nOut;
|
||||
pNew->u.btree.nEq = saved_nEq;
|
||||
pNew->u.btree.nSkip = saved_nSkip;
|
||||
}
|
||||
for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){
|
||||
u16 eOp = pTerm->eOperator; /* Shorthand for pTerm->eOperator */
|
||||
|
73
test/skipscan3.test
Normal file
73
test/skipscan3.test
Normal file
@ -0,0 +1,73 @@
|
||||
# 2014-08-20
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# This file implements tests of the "skip-scan" query strategy.
|
||||
# In particular, this file looks at skipping intermediate terms
|
||||
# in an index. For example, if (a,b,c) are indexed, and we have
|
||||
# "WHERE a=?1 AND c=?2" - verify that skip-scan can still be used.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
do_execsql_test skipscan3-1.1 {
|
||||
CREATE TABLE t1(a,b,c,d,PRIMARY KEY(a,b,c));
|
||||
WITH RECURSIVE
|
||||
c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<1000)
|
||||
INSERT INTO t1(a,b,c,d)
|
||||
SELECT 1, 1, x, printf('x%04d',x) FROM c;
|
||||
ANALYZE;
|
||||
} {}
|
||||
|
||||
# This version has long used skip-scan because of the "+a"
|
||||
#
|
||||
do_execsql_test skipscan3-1.2eqp {
|
||||
EXPLAIN QUERY PLAN SELECT d FROM t1 WHERE +a=1 AND c=32;
|
||||
} {/*ANY(a) AND ANY(b)*/}
|
||||
do_execsql_test skipscan3-1.2 {
|
||||
SELECT d FROM t1 WHERE +a=1 AND c=32;
|
||||
} {x0032}
|
||||
|
||||
# This version (with "a" instead of "+a") should use skip-scan but
|
||||
# did not prior to changes implemented on 2014-08-20
|
||||
#
|
||||
do_execsql_test skipscan3-1.3eqp {
|
||||
EXPLAIN QUERY PLAN SELECT d FROM t1 WHERE a=1 AND c=32;
|
||||
} {/*ANY(a) AND ANY(b)*/}
|
||||
do_execsql_test skipscan3-1.3 {
|
||||
SELECT d FROM t1 WHERE a=1 AND c=32;
|
||||
} {x0032}
|
||||
|
||||
# Repeat the test on a WITHOUT ROWID table
|
||||
#
|
||||
do_execsql_test skipscan3-2.1 {
|
||||
CREATE TABLE t2(a,b,c,d,PRIMARY KEY(a,b,c)) WITHOUT ROWID;
|
||||
WITH RECURSIVE
|
||||
c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<1000)
|
||||
INSERT INTO t2(a,b,c,d)
|
||||
SELECT 1, 1, x, printf('x%04d',x) FROM c;
|
||||
ANALYZE;
|
||||
} {}
|
||||
do_execsql_test skipscan3-2.2eqp {
|
||||
EXPLAIN QUERY PLAN SELECT d FROM t2 WHERE +a=1 AND c=32;
|
||||
} {/*ANY(a) AND ANY(b)*/}
|
||||
do_execsql_test skipscan3-2.2 {
|
||||
SELECT d FROM t2 WHERE +a=1 AND c=32;
|
||||
} {x0032}
|
||||
do_execsql_test skipscan3-2.3eqp {
|
||||
EXPLAIN QUERY PLAN SELECT d FROM t2 WHERE a=1 AND c=32;
|
||||
} {/*ANY(a) AND ANY(b)*/}
|
||||
do_execsql_test skipscan3-2.3 {
|
||||
SELECT d FROM t2 WHERE a=1 AND c=32;
|
||||
} {x0032}
|
||||
|
||||
|
||||
finish_test
|
Loading…
Reference in New Issue
Block a user