-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
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
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
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
-49f44d355ff70744e4951baca2481c7c2b6c02b3
\ No newline at end of file
+bc985caa7816f1f873ad8e4467c5278399f315ce
\ No newline at end of file
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--;
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
** 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
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 */
--- /dev/null
+# 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