]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Experimental planner change to avoid a skip-scan if a regular index scan on exp-avoid-expensive-skipscan
authordan <dan@noemail.net>
Wed, 4 Jul 2018 14:28:07 +0000 (14:28 +0000)
committerdan <dan@noemail.net>
Wed, 4 Jul 2018 14:28:07 +0000 (14:28 +0000)
the same index columns can be done instead.

FossilOrigin-Name: 32924446db0d07e5b2661a6626136a7bcdda629de23f98f3e1e862dd52d2f8a5

manifest
manifest.uuid
src/where.c
test/analyzeG.test [new file with mode: 0644]

index 2357a1bfd45638db86fadd3a4c29a9f9847674f0..3e7e1ec234b6692facfd9798445b955ae6a6d0fa 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Test\sthat\sa\srace\scondition\scan\scause\sa\s"BEGIN\sEXCLUSIVE"\sto\sreturn\nSQLITE_BUSY_SNAPSHOT\sin\swal\smode.
-D 2018-07-03T20:17:27.649
+C Experimental\splanner\schange\sto\savoid\sa\sskip-scan\sif\sa\sregular\sindex\sscan\son\nthe\ssame\sindex\scolumns\scan\sbe\sdone\sinstead.
+D 2018-07-04T14:28:07.015
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F Makefile.in 0a3a6c81e6fcb969ff9106e882f0a08547014ba463cb6beca4c4efaecc924ee6
@@ -580,7 +580,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
 F src/wal.c d44a0811afd2155b1157c38b33141d4ac028fda6232485bed664015bb05819ca
 F src/wal.h 8de5d2d3de0956d6f6cb48c83a4012d5f227b8fe940f3a349a4b7e85ebcb492a
 F src/walker.c ba7225773931760cf60bf22f34d0cce2588df7ce5ce0f215a52eb88234b55ac4
-F src/where.c 0bcbf9e191ca07f9ea2008aa80e70ded46bcdffd26560c83397da501f00aece6
+F src/where.c a38a485f36335c299f1810bcba11fa3cfe7ac10bc6148e4c13500a9c79d59219
 F src/whereInt.h b90ef9b9707ef750eab2a7a080c48fb4900315033274689def32d0cf5a81ebe4
 F src/wherecode.c 3317f2b083a66d3e65a03edf316ade4ccb0a99c9956273282ebb579b95d4ba96
 F src/whereexpr.c 571618c67a3eb5ce0f1158c2792c1aee9b4a4a264392fc4fb1b35467f80abf9a
@@ -612,6 +612,7 @@ F test/analyzeC.test 555a6cc388b9818b6eda6df816f01ce0a75d3a93
 F test/analyzeD.test e50cd0b3e6063216cc0c88a1776e8645dc0bd65a6bb275769cbee33b7fd8d90c
 F test/analyzeE.test 8684e8ac5722fb97c251887ad97e5d496a98af1d
 F test/analyzeF.test 9e1a0537949eb5483642b1140a5c39e5b4025939024b935398471fa552f4dabb
+F test/analyzeG.test 266499f54bb42a56382ac5c8d2efafe7a0d52290395c5bc5b4a1f5254569132f
 F test/analyzer1.test 459fa02c445ddbf0101a3bad47b34290a35f2e49
 F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b
 F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b
@@ -1745,7 +1746,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P b6563647382634588ebe5c6a3c35c65a321dc1b3732c809d48ce46759b9dd80f
-R 85d71bbec8ad4dcf2f8e9507c907b291
+P 5a12db75d1da65daa92413a6b5892309e9d9479bb3610764e1015abe5bf28dbe
+R d1c973cef7dd338d2474c5f688523a12
+T *branch * exp-avoid-expensive-skipscan
+T *sym-exp-avoid-expensive-skipscan *
+T -sym-trunk *
 U dan
-Z 38cb85199c9d8fc14bf46fba2bfb3f49
+Z 68eb1d8d6b0bd6cc041bab15b5fea3f0
index e6f611aeb3068299f474cc80de0323a8778727e4..98e9a2b0fc4a7f1e6511f5af09d3d79fbf2eae36 100644 (file)
@@ -1 +1 @@
-5a12db75d1da65daa92413a6b5892309e9d9479bb3610764e1015abe5bf28dbe
\ No newline at end of file
+32924446db0d07e5b2661a6626136a7bcdda629de23f98f3e1e862dd52d2f8a5
\ No newline at end of file
index 7d537159236d2291c560c0787994a5c4c5af8c2a..bdeaa5fe8df8fa46aeb1c29a3b17c794e4ef9484 100644 (file)
@@ -2043,6 +2043,29 @@ static WhereLoop **whereLoopFindLesser(
       return 0;  /* Discard pTemplate */
     }
 
+    /* If pTemplate:
+    **
+    **   (1) uses the same index as existing where-loop p, 
+    **   (2) requires the same or a superset of tables to be scanned first, 
+    **   (3) constraints the same or fewer columns with ==, and
+    **   (4) skips more leading columns (skip-scan optimization).
+    **
+    ** the discard the template. This ensures that if stat4 data shows that:
+    **
+    **   WHERE (a=1 AND b=2)
+    **
+    ** is prohibitively expensive the planner does not instead do:
+    **
+    **   WHERE (ANY(a) AND b=2)
+    */
+    if( pTemplate->nSkip>p->nSkip                            /* (4) */
+     && pTemplate->u.btree.pIndex==p->u.btree.pIndex         /* (1) */
+     && pTemplate->u.btree.nEq<=p->u.btree.nEq               /* (3) */
+     && (pTemplate->prereq & p->prereq)==p->prereq           /* (2) */
+    ){
+      return 0;  /* Discard pTemplate */
+    }
+
     /* If pTemplate is always better than p, then cause p to be overwritten
     ** with pTemplate.  pTemplate is better than p if:
     **   (1)  pTemplate has no more dependences than p, and
diff --git a/test/analyzeG.test b/test/analyzeG.test
new file mode 100644 (file)
index 0000000..ba45004
--- /dev/null
@@ -0,0 +1,54 @@
+# 2018-07-04
+#
+# 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.
+#
+#***********************************************************************
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+set ::testprefix analyzeG
+
+ifcapable {!stat4} {
+  finish_test
+  return
+}
+
+do_execsql_test 1.0 {
+  CREATE TABLE t1(a, b, c, d);
+  CREATE INDEX t1abc ON t1(a, b, c);
+  WITH s(i) AS (
+    SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100000
+  )
+  INSERT INTO t1 SELECT 1,1,1,1 FROM s;
+
+  WITH s(i) AS (
+    SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<1000
+  )
+  INSERT INTO t1 SELECT i%5,i,i,i FROM s;
+}
+
+do_execsql_test 1.1 {
+  EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=1 AND b=1 AND c>0
+} {
+  3 0 0 {SEARCH TABLE t1 USING INDEX t1abc (a=? AND b=? AND c>?)}
+}
+
+do_execsql_test 1.3 { 
+  ANALYZE 
+} {}
+
+do_execsql_test 1.4 {
+  EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=1 AND b=1 AND c>0
+} {
+  2 0 0 {SCAN TABLE t1}
+}
+
+
+
+finish_test