From: drh Date: Sun, 9 Jun 2013 17:21:25 +0000 (+0000) Subject: High-speed version of NGQP. Still has some minor problems. X-Git-Tag: version-3.8.0~130^2~15^2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=60c96cd7890abc4cf8526afc46b62c971e89b8e2;p=thirdparty%2Fsqlite.git High-speed version of NGQP. Still has some minor problems. FossilOrigin-Name: db2415fa677b84cd0f6dd424283c94e98d246e3b --- diff --git a/manifest b/manifest index d0734bd638..39d6b51064 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Must\sfaster\scomputation\sof\sestimated\slogarithm. -D 2013-06-07T02:04:19.774 +C High-speed\sversion\sof\sNGQP.\s\sStill\shas\ssome\sminor\sproblems. +D 2013-06-09T17:21:25.979 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -289,7 +289,7 @@ F src/vtab.c b05e5f1f4902461ba9f5fc49bb7eb7c3a0741a83 F src/wal.c 436bfceb141b9423c45119e68e444358ee0ed35d F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73 -F src/where.c 70e1ebd1c3f828f4062fc2b5ada2461419020dae +F src/where.c 2dae18fe0b79aa90f213c5f2ff385a7ac56d36d5 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 @@ -1094,7 +1094,10 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 02741d177bfc2fca23bc99974cd899eba13cb59a -R 8ee17766ef9ac6851fd1329c34593963 +P dfbca3acaeb862f24f25e7810a16ff2066111ff4 +R e3ea6bb6c8cd62c47ea6f6e83f99515a +T *branch * nextgen-query-plan-fast +T *sym-nextgen-query-plan-fast * +T -sym-nextgen-query-plan-exp * U drh -Z adf16c6d5fc0c897d258a12782d83ad0 +Z 13597db4c2da76541af04a4f735ffed4 diff --git a/manifest.uuid b/manifest.uuid index 8ae2ff38a7..3a88e72860 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dfbca3acaeb862f24f25e7810a16ff2066111ff4 \ No newline at end of file +db2415fa677b84cd0f6dd424283c94e98d246e3b \ No newline at end of file diff --git a/src/where.c b/src/where.c index c1fc4301d7..135633e1cf 100644 --- a/src/where.c +++ b/src/where.c @@ -5168,6 +5168,75 @@ static int wherePathSolver(WhereInfo *pWInfo, WhereCost nRowEst){ return SQLITE_OK; } +/* +** Most queries use only a single table (they are not joins) and have +** simple == constraints against indexed fields. This routine attempts +** to plan those simple cases using much less ceremony than the +** general-purpose query planner, and thereby yield faster sqlite3_prepare() +** times for the common case. +** +** Return non-zero on success, if this query can be handled by this +** no-frills query planner. Return zero if this query needs the +** general-purpose query planner. +*/ +static int whereSimpleFastCase(WhereLoopBuilder *pBuilder){ + WhereInfo *pWInfo; + struct SrcList_item *pItem; + WhereClause *pWC; + WhereTerm *pTerm; + WhereLoop *pLoop; + int iCur; + int i, j; + int nOrderBy; + Table *pTab; + Index *pIdx; + + pWInfo = pBuilder->pWInfo; + assert( pWInfo->pTabList->nSrc>=1 ); + pItem = pWInfo->pTabList->a; + pTab = pItem->pTab; + if( IsVirtual(pTab) ) return 0; + if( pItem->zIndex ) return 0; + iCur = pItem->iCursor; + pWC = &pWInfo->sWC; + pLoop = pBuilder->pNew; + pWInfo->a[0].pWLoop = pLoop; + pLoop->wsFlags = 0; + nOrderBy = pWInfo->pOrderBy ? pWInfo->pOrderBy->nExpr : 0; + pTerm = findTerm(pWC, iCur, -1, 1, WO_EQ, 0); + if( pTerm ){ + pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_IPK|WHERE_ONEROW; + pLoop->aLTerm[0] = pTerm; + pLoop->nLTerm = 1; + pLoop->u.btree.nEq = 1; + pLoop->rRun = (WhereCost)10; + pLoop->nOut = (WhereCost)1; + pWInfo->nRowOut = 1; + pWInfo->nOBSat = nOrderBy; + }else{ + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + if( pIdx->onError==OE_None ) continue; + for(j=0; jnColumn; j++){ + pTerm = findTerm(pWC, iCur, pIdx->aiColumn[j], 1, WO_EQ, pIdx); + if( pTerm==0 ) break; + whereLoopResize(pWInfo->pParse->db, pLoop, j); + pLoop->aLTerm[j] = pTerm; + } + if( j!=pIdx->nColumn ) continue; + pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_ONEROW; + pLoop->nLTerm = j; + pLoop->u.btree.nEq = j; + pLoop->u.btree.pIndex = pIdx; + pLoop->rRun = (WhereCost)15; + pLoop->nOut = (WhereCost)1; + pWInfo->nRowOut = 1; + pWInfo->nOBSat = nOrderBy; + break; + } + } + return pLoop->wsFlags!=0; +} + /* ** Generate the beginning of the loop used for WHERE clause processing. ** The return value is a pointer to an opaque structure that contains @@ -5307,7 +5376,7 @@ WhereInfo *sqlite3WhereBegin( */ db = pParse->db; nByteWInfo = ROUND8(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel)); - pWInfo = sqlite3DbMallocZero(db, nByteWInfo); + pWInfo = sqlite3DbMallocZero(db, nByteWInfo + sizeof(WhereLoop)); if( db->mallocFailed ){ sqlite3DbFree(db, pWInfo); pWInfo = 0; @@ -5324,6 +5393,8 @@ WhereInfo *sqlite3WhereBegin( pMaskSet = &pWInfo->sMaskSet; sWLB.pWInfo = pWInfo; sWLB.pWC = &pWInfo->sWC; + sWLB.pNew = (WhereLoop*)&pWInfo->a[nTabList]; + whereLoopInit(sWLB.pNew); /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */ @@ -5396,30 +5467,32 @@ WhereInfo *sqlite3WhereBegin( /* Construct the WhereLoop objects */ WHERETRACE(("*** Optimizer Start ***\n")); - /* TBD: if( nTablist==1 ) whereCommonCase(&sWLB); */ - rc = whereLoopAddAll(&sWLB); - if( rc ) goto whereBeginError; - - /* Display all of the WhereLoop objects if wheretrace is enabled */ + if( nTabList!=1 || whereSimpleFastCase(&sWLB)==0 ){ + rc = whereLoopAddAll(&sWLB); + if( rc ) goto whereBeginError; + + /* Display all of the WhereLoop objects if wheretrace is enabled */ #ifdef WHERETRACE_ENABLED - if( sqlite3WhereTrace ){ - WhereLoop *p; - int i = 0; - static char zLabel[] = "0123456789abcdefghijklmnopqrstuvwyxz" - "ABCDEFGHIJKLMNOPQRSTUVWYXZ"; - for(p=pWInfo->pLoops; p; p=p->pNextLoop){ - p->cId = zLabel[(i++)%sizeof(zLabel)]; - whereLoopPrint(p, pTabList); + if( sqlite3WhereTrace ){ + WhereLoop *p; + int i = 0; + static char zLabel[] = "0123456789abcdefghijklmnopqrstuvwyxz" + "ABCDEFGHIJKLMNOPQRSTUVWYXZ"; + for(p=pWInfo->pLoops; p; p=p->pNextLoop){ + p->cId = zLabel[(i++)%sizeof(zLabel)]; + whereLoopPrint(p, pTabList); + } } - } #endif - - wherePathSolver(pWInfo, -1); - if( db->mallocFailed ) goto whereBeginError; - if( pWInfo->pOrderBy ){ - wherePathSolver(pWInfo, pWInfo->nRowOut); - if( db->mallocFailed ) goto whereBeginError; - }else if( db->flags & SQLITE_ReverseOrder ){ + + wherePathSolver(pWInfo, -1); + if( db->mallocFailed ) goto whereBeginError; + if( pWInfo->pOrderBy ){ + wherePathSolver(pWInfo, pWInfo->nRowOut); + if( db->mallocFailed ) goto whereBeginError; + } + } + if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){ pWInfo->revMask = (Bitmask)(-1); } if( pParse->nErr || db->mallocFailed ){