Fix the STAT4 range scan estimates for DESC indexes.
FossilOrigin-Name: e3fe84005259ef9a6027d25793514cebb2d4e7e0
This commit is contained in:
parent
9a7b41d74a
commit
69afd9980e
13
manifest
13
manifest
@ -1,5 +1,5 @@
|
||||
C More\sintuitive\slabels\son\s".wheretrace"\soutput.
|
||||
D 2014-10-08T00:08:08.905
|
||||
C Fix\sthe\sSTAT4\srange\sscan\sestimates\sfor\sDESC\sindexes.
|
||||
D 2014-10-08T02:53:25.568
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@ -302,7 +302,7 @@ F src/vtab.c 019dbfd0406a7447c990e1f7bd1dfcdb8895697f
|
||||
F src/wal.c 10e7de7ce90865a68153f001a61f1d985cd17983
|
||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||
F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804
|
||||
F src/where.c 74e1f7e136bfb52c9c65a55909f8a24873b1edb5
|
||||
F src/where.c 982f1ce21355452f2e5cd284359ab141c1eff547
|
||||
F src/whereInt.h 124d970450955a6982e174b07c320ae6d62a595c
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
@ -327,6 +327,7 @@ F test/analyzeA.test 3335697f6700c7052295cfd0067fc5b2aacddf9a
|
||||
F test/analyzeB.test 8bf35ee0a548aea831bf56762cb8e7fdb1db083d
|
||||
F test/analyzeC.test 555a6cc388b9818b6eda6df816f01ce0a75d3a93
|
||||
F test/analyzeD.test 08f9d0bee4e118a66fff3a32d02dbe0ee0a2b594
|
||||
F test/analyzeE.test 8684e8ac5722fb97c251887ad97e5d496a98af1d
|
||||
F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b
|
||||
F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b
|
||||
F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7
|
||||
@ -1202,7 +1203,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 f672a380e2e52bede95ff11a533fd9f7d412d494
|
||||
R b98bb7ee2a60e85b3c67deaa06ee1000
|
||||
P adcb3fed489b580221c7bf2692a60e24248b23a0
|
||||
R 50f3751b824cfe9cc6f7ad401beb29e1
|
||||
U drh
|
||||
Z 71a8e8f52b1016a5adbdd28eb6eb38bb
|
||||
Z 07946a58b794ebe5e4cb12afd1dbd645
|
||||
|
@ -1 +1 @@
|
||||
adcb3fed489b580221c7bf2692a60e24248b23a0
|
||||
e3fe84005259ef9a6027d25793514cebb2d4e7e0
|
13
src/where.c
13
src/where.c
@ -2207,16 +2207,22 @@ static int whereRangeScanEst(
|
||||
iUpper = a[0] + a[1];
|
||||
}
|
||||
|
||||
assert( pLower==0 || (pLower->eOperator & (WO_GT|WO_GE))!=0 );
|
||||
assert( pUpper==0 || (pUpper->eOperator & (WO_LT|WO_LE))!=0 );
|
||||
if( p->pKeyInfo && p->pKeyInfo->aSortOrder[nEq] ){
|
||||
/* The roles of pLower and pUpper are swapped for a DESC index */
|
||||
SWAP(WhereTerm*, pLower, pUpper);
|
||||
}
|
||||
|
||||
/* If possible, improve on the iLower estimate using ($P:$L). */
|
||||
if( pLower ){
|
||||
int bOk; /* True if value is extracted from pExpr */
|
||||
Expr *pExpr = pLower->pExpr->pRight;
|
||||
assert( (pLower->eOperator & (WO_GT|WO_GE))!=0 );
|
||||
rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
|
||||
if( rc==SQLITE_OK && bOk ){
|
||||
tRowcnt iNew;
|
||||
whereKeyStats(pParse, p, pRec, 0, a);
|
||||
iNew = a[0] + ((pLower->eOperator & WO_GT) ? a[1] : 0);
|
||||
iNew = a[0] + ((pLower->eOperator & (WO_GT|WO_LE)) ? a[1] : 0);
|
||||
if( iNew>iLower ) iLower = iNew;
|
||||
nOut--;
|
||||
pLower = 0;
|
||||
@ -2227,12 +2233,11 @@ static int whereRangeScanEst(
|
||||
if( pUpper ){
|
||||
int bOk; /* True if value is extracted from pExpr */
|
||||
Expr *pExpr = pUpper->pExpr->pRight;
|
||||
assert( (pUpper->eOperator & (WO_LT|WO_LE))!=0 );
|
||||
rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
|
||||
if( rc==SQLITE_OK && bOk ){
|
||||
tRowcnt iNew;
|
||||
whereKeyStats(pParse, p, pRec, 1, a);
|
||||
iNew = a[0] + ((pUpper->eOperator & WO_LE) ? a[1] : 0);
|
||||
iNew = a[0] + ((pUpper->eOperator & (WO_GT|WO_LE)) ? a[1] : 0);
|
||||
if( iNew<iUpper ) iUpper = iNew;
|
||||
nOut--;
|
||||
pUpper = 0;
|
||||
|
242
test/analyzeE.test
Normal file
242
test/analyzeE.test
Normal file
@ -0,0 +1,242 @@
|
||||
# 2014-10-08
|
||||
#
|
||||
# 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 for using STAT4 information
|
||||
# on a descending index in a range query.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set ::testprefix analyzeE
|
||||
|
||||
ifcapable {!stat4} {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
# Verify that range queries on an ASCENDING index will use the
|
||||
# index only if the range covers only a small fraction of the
|
||||
# entries.
|
||||
#
|
||||
do_execsql_test analyzeE-1.0 {
|
||||
CREATE TABLE t1(a,b);
|
||||
WITH RECURSIVE
|
||||
cnt(x) AS (VALUES(1000) UNION ALL SELECT x+1 FROM cnt WHERE x<2000)
|
||||
INSERT INTO t1(a,b) SELECT x, x FROM cnt;
|
||||
CREATE INDEX t1a ON t1(a);
|
||||
ANALYZE;
|
||||
} {}
|
||||
do_execsql_test analyzeE-1.1 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a BETWEEN 500 AND 2500;
|
||||
} {/SCAN TABLE t1/}
|
||||
do_execsql_test analyzeE-1.2 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a BETWEEN 2900 AND 3000;
|
||||
} {/SEARCH TABLE t1 USING INDEX t1a/}
|
||||
do_execsql_test analyzeE-1.3 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a BETWEEN 1700 AND 1750;
|
||||
} {/SEARCH TABLE t1 USING INDEX t1a/}
|
||||
do_execsql_test analyzeE-1.4 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a BETWEEN 1 AND 500
|
||||
} {/SEARCH TABLE t1 USING INDEX t1a/}
|
||||
do_execsql_test analyzeE-1.5 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a BETWEEN 3000 AND 3000000
|
||||
} {/SEARCH TABLE t1 USING INDEX t1a/}
|
||||
do_execsql_test analyzeE-1.6 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a<500
|
||||
} {/SEARCH TABLE t1 USING INDEX t1a/}
|
||||
do_execsql_test analyzeE-1.7 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a>2500
|
||||
} {/SEARCH TABLE t1 USING INDEX t1a/}
|
||||
do_execsql_test analyzeE-1.8 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a>1900
|
||||
} {/SEARCH TABLE t1 USING INDEX t1a/}
|
||||
do_execsql_test analyzeE-1.9 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a>1100
|
||||
} {/SCAN TABLE t1/}
|
||||
do_execsql_test analyzeE-1.10 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a<1100
|
||||
} {/SEARCH TABLE t1 USING INDEX t1a/}
|
||||
do_execsql_test analyzeE-1.11 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a<1900
|
||||
} {/SCAN TABLE t1/}
|
||||
|
||||
# Verify that everything works the same on a DESCENDING index.
|
||||
#
|
||||
do_execsql_test analyzeE-2.0 {
|
||||
DROP INDEX t1a;
|
||||
CREATE INDEX t1a ON t1(a DESC);
|
||||
ANALYZE;
|
||||
} {}
|
||||
do_execsql_test analyzeE-2.1 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a BETWEEN 500 AND 2500;
|
||||
} {/SCAN TABLE t1/}
|
||||
do_execsql_test analyzeE-2.2 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a BETWEEN 2900 AND 3000;
|
||||
} {/SEARCH TABLE t1 USING INDEX t1a/}
|
||||
do_execsql_test analyzeE-2.3 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a BETWEEN 1700 AND 1750;
|
||||
} {/SEARCH TABLE t1 USING INDEX t1a/}
|
||||
do_execsql_test analyzeE-2.4 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a BETWEEN 1 AND 500
|
||||
} {/SEARCH TABLE t1 USING INDEX t1a/}
|
||||
do_execsql_test analyzeE-2.5 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a BETWEEN 3000 AND 3000000
|
||||
} {/SEARCH TABLE t1 USING INDEX t1a/}
|
||||
do_execsql_test analyzeE-2.6 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a<500
|
||||
} {/SEARCH TABLE t1 USING INDEX t1a/}
|
||||
do_execsql_test analyzeE-2.7 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a>2500
|
||||
} {/SEARCH TABLE t1 USING INDEX t1a/}
|
||||
do_execsql_test analyzeE-2.8 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a>1900
|
||||
} {/SEARCH TABLE t1 USING INDEX t1a/}
|
||||
do_execsql_test analyzeE-2.9 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a>1100
|
||||
} {/SCAN TABLE t1/}
|
||||
do_execsql_test analyzeE-2.10 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a<1100
|
||||
} {/SEARCH TABLE t1 USING INDEX t1a/}
|
||||
do_execsql_test analyzeE-2.11 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a<1900
|
||||
} {/SCAN TABLE t1/}
|
||||
|
||||
# Now do a range query on the second term of an ASCENDING index
|
||||
# where the first term is constrained by equality.
|
||||
#
|
||||
do_execsql_test analyzeE-3.0 {
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1(a,b,c);
|
||||
WITH RECURSIVE
|
||||
cnt(x) AS (VALUES(1000) UNION ALL SELECT x+1 FROM cnt WHERE x<2000)
|
||||
INSERT INTO t1(a,b,c) SELECT x, x, 123 FROM cnt;
|
||||
CREATE INDEX t1ca ON t1(c,a);
|
||||
ANALYZE;
|
||||
} {}
|
||||
do_execsql_test analyzeE-3.1 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a BETWEEN 500 AND 2500 AND c=123;
|
||||
} {/SCAN TABLE t1/}
|
||||
do_execsql_test analyzeE-3.2 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a BETWEEN 2900 AND 3000 AND c=123;
|
||||
} {/SEARCH TABLE t1 USING INDEX t1ca/}
|
||||
do_execsql_test analyzeE-3.3 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a BETWEEN 1700 AND 1750 AND c=123;
|
||||
} {/SEARCH TABLE t1 USING INDEX t1ca/}
|
||||
do_execsql_test analyzeE-3.4 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a BETWEEN 1 AND 500 AND c=123
|
||||
} {/SEARCH TABLE t1 USING INDEX t1ca/}
|
||||
do_execsql_test analyzeE-3.5 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a BETWEEN 3000 AND 3000000 AND c=123
|
||||
} {/SEARCH TABLE t1 USING INDEX t1ca/}
|
||||
do_execsql_test analyzeE-3.6 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a<500 AND c=123
|
||||
} {/SEARCH TABLE t1 USING INDEX t1ca/}
|
||||
do_execsql_test analyzeE-3.7 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a>2500 AND c=123
|
||||
} {/SEARCH TABLE t1 USING INDEX t1ca/}
|
||||
do_execsql_test analyzeE-3.8 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a>1900 AND c=123
|
||||
} {/SEARCH TABLE t1 USING INDEX t1ca/}
|
||||
do_execsql_test analyzeE-3.9 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a>1100 AND c=123
|
||||
} {/SCAN TABLE t1/}
|
||||
do_execsql_test analyzeE-3.10 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a<1100 AND c=123
|
||||
} {/SEARCH TABLE t1 USING INDEX t1ca/}
|
||||
do_execsql_test analyzeE-3.11 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a<1900 AND c=123
|
||||
} {/SCAN TABLE t1/}
|
||||
|
||||
# Repeat the 3.x tests using a DESCENDING index
|
||||
#
|
||||
do_execsql_test analyzeE-4.0 {
|
||||
DROP INDEX t1ca;
|
||||
CREATE INDEX t1ca ON t1(c ASC,a DESC);
|
||||
ANALYZE;
|
||||
} {}
|
||||
do_execsql_test analyzeE-4.1 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a BETWEEN 500 AND 2500 AND c=123;
|
||||
} {/SCAN TABLE t1/}
|
||||
do_execsql_test analyzeE-4.2 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a BETWEEN 2900 AND 3000 AND c=123;
|
||||
} {/SEARCH TABLE t1 USING INDEX t1ca/}
|
||||
do_execsql_test analyzeE-4.3 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a BETWEEN 1700 AND 1750 AND c=123;
|
||||
} {/SEARCH TABLE t1 USING INDEX t1ca/}
|
||||
do_execsql_test analyzeE-4.4 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a BETWEEN 1 AND 500 AND c=123
|
||||
} {/SEARCH TABLE t1 USING INDEX t1ca/}
|
||||
do_execsql_test analyzeE-4.5 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a BETWEEN 3000 AND 3000000 AND c=123
|
||||
} {/SEARCH TABLE t1 USING INDEX t1ca/}
|
||||
do_execsql_test analyzeE-4.6 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a<500 AND c=123
|
||||
} {/SEARCH TABLE t1 USING INDEX t1ca/}
|
||||
do_execsql_test analyzeE-4.7 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a>2500 AND c=123
|
||||
} {/SEARCH TABLE t1 USING INDEX t1ca/}
|
||||
do_execsql_test analyzeE-4.8 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a>1900 AND c=123
|
||||
} {/SEARCH TABLE t1 USING INDEX t1ca/}
|
||||
do_execsql_test analyzeE-4.9 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a>1100 AND c=123
|
||||
} {/SCAN TABLE t1/}
|
||||
do_execsql_test analyzeE-4.10 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a<1100 AND c=123
|
||||
} {/SEARCH TABLE t1 USING INDEX t1ca/}
|
||||
do_execsql_test analyzeE-4.11 {
|
||||
EXPLAIN QUERY PLAN
|
||||
SELECT * FROM t1 WHERE a<1900 AND c=123
|
||||
} {/SCAN TABLE t1/}
|
||||
|
||||
finish_test
|
Loading…
x
Reference in New Issue
Block a user