1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-12 13:01:09 +03:00

Attempt to disable inner loops of a join that do not generate output.

This does not work, since the inner loops might run zero times and thus
inhibit all output.  Needs to be enhanced to work only for LEFT JOINs
or when we know that the inner loop will always run at least once.

FossilOrigin-Name: ca839723a21bb13d3e0666a672c15c6f3a267c2f
This commit is contained in:
drh
2013-06-21 02:05:06 +00:00
parent 6457a353bc
commit fd636c7541
4 changed files with 43 additions and 28 deletions

View File

@@ -1,5 +1,5 @@
C Modify\sthe\squery\splanner\sinterface\sso\sthat\sit\salways\spasses\sin\sthe\sresult\sset.\nThis\sis\sthe\sfirst\sstep\stoward\sadding\san\soptimization\sthat\swill\somit\stables\nfrom\sa\sjoin\sthat\sdo\snot\scontribute\sto\sthe\sresult. C Attempt\sto\sdisable\sinner\sloops\sof\sa\sjoin\sthat\sdo\snot\sgenerate\soutput.\nThis\sdoes\snot\swork,\ssince\sthe\sinner\sloops\smight\srun\szero\stimes\sand\sthus\ninhibit\sall\soutput.\s\sNeeds\sto\sbe\senhanced\sto\swork\sonly\sfor\sLEFT\sJOINs\nor\swhen\swe\sknow\sthat\sthe\sinner\sloop\swill\salways\srun\sat\sleast\sonce.
D 2013-06-21T00:35:37.456 D 2013-06-21T02:05:06.206
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -289,14 +289,14 @@ F src/vtab.c b05e5f1f4902461ba9f5fc49bb7eb7c3a0741a83
F src/wal.c 436bfceb141b9423c45119e68e444358ee0ed35d F src/wal.c 436bfceb141b9423c45119e68e444358ee0ed35d
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73 F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73
F src/where.c c950b131584a40121092d735804472f567beefbc F src/where.c fc5293b54a70474c2b46e9df26c9e2803b152e68
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
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
F test/all.test 6ff7b43c2b4b905c74dc4a813d201d0fa64c5783 F test/all.test 6ff7b43c2b4b905c74dc4a813d201d0fa64c5783
F test/alter.test 57d96ec9b320bd07af77567034488dcb6642c748 F test/alter.test 57d96ec9b320bd07af77567034488dcb6642c748
F test/alter2.test 40531b1f89d4fe43f9007b1bfc304e291ed000ae F test/alter2.test 7ea05c7d92ac99349a802ef7ada17294dd647060
F test/alter3.test 49c9d9fba2b8fcdce2dedeca97bbf1f369cc548d F test/alter3.test 49c9d9fba2b8fcdce2dedeca97bbf1f369cc548d
F test/alter4.test b2debc14d8cbe4c1d12ccd6a41eef88a8c1f15d5 F test/alter4.test b2debc14d8cbe4c1d12ccd6a41eef88a8c1f15d5
F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc
@@ -1096,10 +1096,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
P 604c3c5de6fd8f8a569aa9ed981055a5b0123ba1 P 2c2577e69ccb47f1af674a755e71221e2ca0b322
R 54a7c9b08c105a408dfe2c4fd7fd4419 R b2263c66dd8a59884ee45351c335261a
T *branch * omit-join-table-opt
T *sym-omit-join-table-opt *
T -sym-nextgen-query-plan-exp *
U drh U drh
Z d2a3072c8b463b513f8068b32a4cb830 Z 6fd83e64fe937f64082b799e88969f81

View File

@@ -1 +1 @@
2c2577e69ccb47f1af674a755e71221e2ca0b322 ca839723a21bb13d3e0666a672c15c6f3a267c2f

View File

@@ -392,10 +392,10 @@ struct WhereInfo {
u8 okOnePass; /* Ok to use one-pass algorithm for UPDATE/DELETE */ u8 okOnePass; /* Ok to use one-pass algorithm for UPDATE/DELETE */
u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */ u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */
u8 eDistinct; /* One of the WHERE_DISTINCT_* values below */ u8 eDistinct; /* One of the WHERE_DISTINCT_* values below */
u8 nLevel; /* Number of nested loop */
int iTop; /* The very beginning of the WHERE loop */ int iTop; /* The very beginning of the WHERE loop */
int iContinue; /* Jump here to continue with next record */ int iContinue; /* Jump here to continue with next record */
int iBreak; /* Jump here to break out of the loop */ int iBreak; /* Jump here to break out of the loop */
int nLevel; /* Number of nested loop */
int savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */ int savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */
WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */ WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */
WhereClause sWC; /* Decomposition of the WHERE clause */ WhereClause sWC; /* Decomposition of the WHERE clause */
@@ -5370,8 +5370,9 @@ static int wherePathSolver(WhereInfo *pWInfo, WhereCost nRowEst){
pLevel->iFrom = pWLoop->iTab; pLevel->iFrom = pWLoop->iTab;
pLevel->iTabCur = pWInfo->pTabList->a[pLevel->iFrom].iCursor; pLevel->iTabCur = pWInfo->pTabList->a[pLevel->iFrom].iCursor;
} }
if( (pWInfo->wctrlFlags & (WHERE_DISTINCTBY|WHERE_WANT_DISTINCT)) if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)!=0
==WHERE_WANT_DISTINCT && (pWInfo->wctrlFlags & WHERE_DISTINCTBY)==0
&& pWInfo->eDistinct==WHERE_DISTINCT_NOOP
&& nRowEst && nRowEst
){ ){
Bitmask notUsed; Bitmask notUsed;
@@ -5571,15 +5572,23 @@ WhereInfo *sqlite3WhereBegin(
WhereLoopBuilder sWLB; /* The WhereLoop builder */ WhereLoopBuilder sWLB; /* The WhereLoop builder */
WhereMaskSet *pMaskSet; /* The expression mask set */ WhereMaskSet *pMaskSet; /* The expression mask set */
WhereLevel *pLevel; /* A single level in pWInfo->a[] */ WhereLevel *pLevel; /* A single level in pWInfo->a[] */
WhereLoop *pLoop; /* Pointer to a single WhereLoop object */
int ii; /* Loop counter */ int ii; /* Loop counter */
sqlite3 *db; /* Database connection */ sqlite3 *db; /* Database connection */
int rc; /* Return code */ int rc; /* Return code */
/* Variable initialization */ /* Variable initialization */
db = pParse->db;
memset(&sWLB, 0, sizeof(sWLB)); memset(&sWLB, 0, sizeof(sWLB));
sWLB.pOrderBy = pOrderBy; sWLB.pOrderBy = pOrderBy;
/* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via
** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */
if( OptimizationDisabled(db, SQLITE_DistinctOpt) ){
wctrlFlags &= ~WHERE_WANT_DISTINCT;
}
/* The number of tables in the FROM clause is limited by the number of /* The number of tables in the FROM clause is limited by the number of
** bits in a Bitmask ** bits in a Bitmask
*/ */
@@ -5603,7 +5612,6 @@ WhereInfo *sqlite3WhereBegin(
** field (type Bitmask) it must be aligned on an 8-byte boundary on ** field (type Bitmask) it must be aligned on an 8-byte boundary on
** some architectures. Hence the ROUND8() below. ** some architectures. Hence the ROUND8() below.
*/ */
db = pParse->db;
nByteWInfo = ROUND8(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel)); nByteWInfo = ROUND8(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel));
pWInfo = sqlite3DbMallocZero(db, nByteWInfo + sizeof(WhereLoop)); pWInfo = sqlite3DbMallocZero(db, nByteWInfo + sizeof(WhereLoop));
if( db->mallocFailed ){ if( db->mallocFailed ){
@@ -5628,12 +5636,6 @@ WhereInfo *sqlite3WhereBegin(
sWLB.pNew->cId = '*'; sWLB.pNew->cId = '*';
#endif #endif
/* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via
** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */
if( OptimizationDisabled(db, SQLITE_DistinctOpt) ){
wctrlFlags &= ~WHERE_WANT_DISTINCT;
}
/* Split the WHERE clause into separate subexpressions where each /* Split the WHERE clause into separate subexpressions where each
** subexpression is separated by an AND operator. ** subexpression is separated by an AND operator.
*/ */
@@ -5718,7 +5720,6 @@ WhereInfo *sqlite3WhereBegin(
if( wctrlFlags & WHERE_WANT_DISTINCT ){ if( wctrlFlags & WHERE_WANT_DISTINCT ){
if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){ if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){
/* The DISTINCT marking is pointless. Ignore it. */ /* The DISTINCT marking is pointless. Ignore it. */
wctrlFlags &= ~WHERE_WANT_DISTINCT;
pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
}else if( pOrderBy==0 ){ }else if( pOrderBy==0 ){
/* Try to ORDER BY the result set to make distinct processing easier */ /* Try to ORDER BY the result set to make distinct processing easier */
@@ -5737,11 +5738,11 @@ WhereInfo *sqlite3WhereBegin(
#ifdef WHERETRACE_ENABLED #ifdef WHERETRACE_ENABLED
if( sqlite3WhereTrace ){ if( sqlite3WhereTrace ){
WhereLoop *p; WhereLoop *p;
int i = 0; int i;
static char zLabel[] = "0123456789abcdefghijklmnopqrstuvwyxz" static char zLabel[] = "0123456789abcdefghijklmnopqrstuvwyxz"
"ABCDEFGHIJKLMNOPQRSTUVWYXZ"; "ABCDEFGHIJKLMNOPQRSTUVWYXZ";
for(p=pWInfo->pLoops; p; p=p->pNextLoop){ for(p=pWInfo->pLoops, i=0; p; p=p->pNextLoop, i++){
p->cId = zLabel[(i++)%sizeof(zLabel)]; p->cId = zLabel[i%sizeof(zLabel)];
whereLoopPrint(p, pTabList); whereLoopPrint(p, pTabList);
} }
} }
@@ -5782,11 +5783,29 @@ WhereInfo *sqlite3WhereBegin(
} }
} }
sqlite3DebugPrintf("\n"); sqlite3DebugPrintf("\n");
for(ii=0; ii<nTabList; ii++){ for(ii=0; ii<pWInfo->nLevel; ii++){
whereLoopPrint(pWInfo->a[ii].pWLoop, pTabList); whereLoopPrint(pWInfo->a[ii].pWLoop, pTabList);
} }
} }
#endif #endif
/* Attempt to omit tables from the join that do not effect the result */
if( pResultSet!=0 && pWInfo->nLevel>=2 ){
Bitmask tabUsed = exprListTableUsage(pMaskSet, pResultSet);
if( pOrderBy ) tabUsed |= exprListTableUsage(pMaskSet, pOrderBy);
while( pWInfo->nLevel>=2 ){
pLoop = pWInfo->a[pWInfo->nLevel-1].pWLoop;
if( ((wctrlFlags & WHERE_WANT_DISTINCT)!=0
|| (pLoop->wsFlags & WHERE_ONEROW)!=0)
&& (tabUsed & pLoop->maskSelf)==0
){
WHERETRACE(0xffff, ("-> drop loop %c not used\n", pLoop->cId));
pWInfo->nLevel--;
nTabList--;
}else{
break;
}
}
}
WHERETRACE(0xffff,("*** Optimizer Finished ***\n")); WHERETRACE(0xffff,("*** Optimizer Finished ***\n"));
pWInfo->pParse->nQueryLoop += pWInfo->nRowOut; pWInfo->pParse->nQueryLoop += pWInfo->nRowOut;
@@ -5955,7 +5974,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){
/* Close all of the cursors that were opened by sqlite3WhereBegin. /* Close all of the cursors that were opened by sqlite3WhereBegin.
*/ */
assert( pWInfo->nLevel==1 || pWInfo->nLevel==pTabList->nSrc ); assert( pWInfo->nLevel<=pTabList->nSrc );
for(i=0, pLevel=pWInfo->a; i<pWInfo->nLevel; i++, pLevel++){ for(i=0, pLevel=pWInfo->a; i<pWInfo->nLevel; i++, pLevel++){
Index *pIdx = 0; Index *pIdx = 0;
struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom]; struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom];

View File

@@ -120,7 +120,6 @@ do_test alter2-1.5 {
} }
} {} } {}
do_test alter2-1.6 { do_test alter2-1.6 {
breakpoint
execsql { execsql {
SELECT c FROM abc ORDER BY c; SELECT c FROM abc ORDER BY c;
} }