From: drh Date: Tue, 16 Nov 2010 02:49:15 +0000 (+0000) Subject: Use the estimated number of rows computed for subqueries in the cost X-Git-Tag: version-3.7.4~54 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=95aa47b10a6ff9e920ee82b1dcde8c8ed73c69c2;p=thirdparty%2Fsqlite.git Use the estimated number of rows computed for subqueries in the cost computations for outer queries. FossilOrigin-Name: 56bbc539246a6dc9f1ae1edb898db7a4f6f6d322 --- diff --git a/manifest b/manifest index 6afe3705c5..d06d475d13 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Change\sthe\sEQP\soutput\sfor\sthe\smin/max\soptimization\sfrom\s"SCAN"\sto\s"SEARCH".\nOther\schanges\sin\swhere.c\sin\ssupport\sof\sfull\sbranch\scoverage\stesting. -D 2010-11-15T21:50:20 +C Use\sthe\sestimated\snumber\sof\srows\scomputed\sfor\ssubqueries\sin\sthe\scost\ncomputations\sfor\souter\squeries. +D 2010-11-16T02:49:16 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e7a59672eaeb04408d1fa8501618d7501a3c5e39 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -177,11 +177,11 @@ F src/printf.c 8ae5082dd38a1b5456030c3755ec3a392cd51506 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 -F src/select.c a88ad1cb4af99e47548760d4dd400d2405baff3c +F src/select.c 550d67688f5e8bc8022faf6d014838afba1415af F src/shell.c 8517fc1f9c59ae4007e6cc8b9af91ab231ea2056 F src/sqlite.h.in f47e09412fc9a129f759fa4d96ef21f4b3d529eb F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754 -F src/sqliteInt.h 8648d013cea93d204faf0959743c47bacd65a85d +F src/sqliteInt.h dd28f6138c74cf4833e032a989b6ff7885798cf6 F src/sqliteLimit.h a17dcd3fb775d63b64a43a55c54cb282f9726f44 F src/status.c 496913d4e8441195f6f2a75b1c95993a45b9b30b F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -242,7 +242,7 @@ F src/vtab.c b297e8fa656ab5e66244ab15680d68db0adbec30 F src/wal.c f26b8d297bd11cb792e609917f9d4c6718ac8e0e F src/wal.h c1aac6593a0b02b15dc625987e619edeab39292e F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f -F src/where.c 6ba0540b6f0239351f2e29b66f1565fe18ef53fe +F src/where.c d5cc65f51661a038a2c6a663a945d5cf4c277b81 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 F test/all.test 6745008c144bd2956d58864d21f7b304689c1cce @@ -267,7 +267,7 @@ F test/auth.test 26cc6f219580191539bf335abe03e55e49310846 F test/auth2.test 270baddc8b9c273682760cffba6739d907bd2882 F test/auth3.test a4755e6a2a2fea547ffe63c874eb569e60a28eb5 F test/autoinc.test 85ef3180a737e6580086a018c09c6f1a52759b46 -F test/autoindex1.test 67e2de552a458db13a2eab4fefb291b84f87db5c +F test/autoindex1.test 860fc83f4fefb0c68ad062afc3ff43faa1534fc4 F test/autovacuum.test bb7c0885e6f8f1d633045de48f2b66082162766d F test/autovacuum_ioerr2.test 598b0663074d3673a9c1bc9a16e80971313bafe6 F test/avtrans.test 0252654f4295ddda3b2cce0e894812259e655a85 @@ -368,7 +368,7 @@ F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea F test/enc2.test 6d91a5286f59add0cfcbb2d0da913b76f2242398 F test/enc3.test 5c550d59ff31dccdba5d1a02ae11c7047d77c041 F test/enc4.test 4b575ef09e0eff896e73bd24076f96c2aa6a42de -F test/eqp.test 7cc9b11f92398843928c2c63525192d4dfdf8df6 +F test/eqp.test 69670e7919030f21de29fb99bf1d68f97aedcbdb F test/eval.test bc269c365ba877554948441e91ad5373f9f91be3 F test/exclusive.test 53e1841b422e554cecf0160f937c473d6d0e3062 F test/exclusive2.test 76e63c05349cb70d09d60b99d2ae625525ff5155 @@ -889,14 +889,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 136c2ac24ee1663bc0904bce1a619ecef3d11c1c -R 5f0193dbeb0cbc5cfdd968905645aae6 +P d52b593978aa1776af7aeb957c4f8df0c5cb7e43 +R d49dbce342d6074d2c08ca15a1061dc2 U drh -Z 99e502199a00f309bbcf4dd70b11c16e +Z 1d0a2a683be8d99ef69f89af3e0fc4c3 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFM4asfoxKgR168RlERAr0gAJ9X2nb2tbe+17ybbefiHGEsu/utZgCfQE+r -khXtw5KolxWbb2vTQFeG+m0= -=SW32 +iD8DBQFM4fEvoxKgR168RlERAtLBAJ0duCZxNY8VlhlVLo/NezKrqI5noACdE3GU +LDKZgeEbRVz6H1/mucVVNUQ= +=B2su -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 1e03318a09..5f256ca04e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d52b593978aa1776af7aeb957c4f8df0c5cb7e43 \ No newline at end of file +56bbc539246a6dc9f1ae1edb898db7a4f6f6d322 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 0f83bbb36f..5c5b615899 100644 --- a/src/select.c +++ b/src/select.c @@ -1433,6 +1433,8 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ VdbeComment((v, "LIMIT counter")); if( n==0 ){ sqlite3VdbeAddOp2(v, OP_Goto, 0, iBreak); + }else{ + if( p->nSelectRow > (double)n ) p->nSelectRow = (double)n; } }else{ sqlite3ExprCode(pParse, p->pLimit, iLimit); @@ -1594,6 +1596,7 @@ static int multiSelect( switch( p->op ){ case TK_ALL: { int addr = 0; + int nLimit; assert( !pPrior->pLimit ); pPrior->pLimit = p->pLimit; pPrior->pOffset = p->pOffset; @@ -1616,6 +1619,13 @@ static int multiSelect( testcase( rc!=SQLITE_OK ); pDelete = p->pPrior; p->pPrior = pPrior; + p->nSelectRow += pPrior->nSelectRow; + if( pPrior->pLimit + && sqlite3ExprIsInteger(pPrior->pLimit, &nLimit) + && p->nSelectRow > (double)nLimit + ){ + p->nSelectRow = (double)nLimit; + } if( addr ){ sqlite3VdbeJumpHere(v, addr); } @@ -1688,6 +1698,7 @@ static int multiSelect( pDelete = p->pPrior; p->pPrior = pPrior; p->pOrderBy = 0; + if( p->op==TK_UNION ) p->nSelectRow += pPrior->nSelectRow; sqlite3ExprDelete(db, p->pLimit); p->pLimit = pLimit; p->pOffset = pOffset; @@ -1767,6 +1778,7 @@ static int multiSelect( testcase( rc!=SQLITE_OK ); pDelete = p->pPrior; p->pPrior = pPrior; + if( p->nSelectRow>pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow; sqlite3ExprDelete(db, p->pLimit); p->pLimit = pLimit; p->pOffset = pOffset; @@ -2353,6 +2365,7 @@ static int multiSelectOrderBy( sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB); sqlite3VdbeAddOp1(v, OP_Yield, regAddrB); sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofA); + p->nSelectRow += pPrior->nSelectRow; } /* Generate a subroutine to run when the results from select B @@ -2360,6 +2373,7 @@ static int multiSelectOrderBy( */ if( op==TK_INTERSECT ){ addrEofB = addrEofA; + if( p->nSelectRow > pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow; }else{ VdbeNoopComment((v, "eof-B subroutine")); addrEofB = sqlite3VdbeAddOp2(v, OP_If, regEofA, labelEnd); @@ -3754,6 +3768,7 @@ int sqlite3Select( explainSetInteger(pItem->iSelectId, pParse->iNextSelectId); sqlite3Select(pParse, pSub, &dest); pItem->isPopulated = 1; + pItem->pTab->nRowEst = (unsigned)pSub->nSelectRow; } if( /*pParse->nErr ||*/ db->mallocFailed ){ goto select_end; @@ -3846,6 +3861,7 @@ int sqlite3Select( /* Set the limiter. */ iEnd = sqlite3VdbeMakeLabel(v); + p->nSelectRow = (double)LARGEST_INT64; computeLimitRegisters(pParse, p, iEnd); /* Open a virtual index to use for the distinct set. @@ -3869,6 +3885,7 @@ int sqlite3Select( */ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pOrderBy, 0); if( pWInfo==0 ) goto select_end; + if( pWInfo->nRowOut < p->nSelectRow ) p->nSelectRow = pWInfo->nRowOut; /* If sorting index that was created by a prior OP_OpenEphemeral ** instruction ended up not being needed, then change the OP_OpenEphemeral @@ -3913,6 +3930,9 @@ int sqlite3Select( for(k=pGroupBy->nExpr, pItem=pGroupBy->a; k>0; k--, pItem++){ pItem->iAlias = 0; } + if( p->nSelectRow>(double)100 ) p->nSelectRow = (double)100; + }else{ + p->nSelectRow = (double)1; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index b9eb650d82..c02a0e4487 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1947,6 +1947,7 @@ struct WhereInfo { int nLevel; /* Number of nested loop */ struct WhereClause *pWC; /* Decomposition of the WHERE clause */ double savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */ + double nRowOut; /* Estimated number of output rows */ WhereLevel a[1]; /* Information about each nest loop in WHERE */ }; @@ -2022,6 +2023,7 @@ struct Select { Expr *pOffset; /* OFFSET expression. NULL means not used. */ int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */ int addrOpenEphm[3]; /* OP_OpenEphem opcodes related to this select */ + double nSelectRow; /* Estimated number of result rows */ }; /* diff --git a/src/where.c b/src/where.c index 1d6641ee8b..751c7a99c2 100644 --- a/src/where.c +++ b/src/where.c @@ -4423,6 +4423,7 @@ WhereInfo *sqlite3WhereBegin( */ sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */ notReady = ~(Bitmask)0; + pWInfo->nRowOut = (double)1; for(i=0, pLevel=pWInfo->a; ia[pLevel->iFrom]; pTab = pTabItem->pTab; pLevel->iTabCur = pTabItem->iCursor; + pWInfo->nRowOut *= pLevel->plan.nRow; iDb = sqlite3SchemaToIndex(db, pTab->pSchema); if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ){ /* Do nothing */ diff --git a/test/autoindex1.test b/test/autoindex1.test index 6552fe8b3b..bc628dc256 100644 --- a/test/autoindex1.test +++ b/test/autoindex1.test @@ -245,7 +245,7 @@ do_execsql_test autoindex1-600 { 1 0 0 {EXECUTE CORRELATED SCALAR SUBQUERY 2} 2 0 0 {SEARCH TABLE flock_owner AS later USING COVERING INDEX sqlite_autoindex_flock_owner_1 (flock_no=? AND owner_change_date>? AND owner_change_date