From: drh Date: Mon, 28 Sep 2015 23:45:19 +0000 (+0000) Subject: Avoid unnecessary cursors and seeking when running a DELETE against a X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1f8bb50d9417e7bd572cb7d109d9d6d80c76194e;p=thirdparty%2Fsqlite.git Avoid unnecessary cursors and seeking when running a DELETE against a WITHOUT ROWID table. FossilOrigin-Name: 70ec88b29982f1a2437239ad4d3a9bf39bcc2a60 --- diff --git a/manifest b/manifest index 6bcfc15a78..c4de5a2693 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Extra\sinformation\sprovided\sby\s.wheretrace\son\sinput\sflags\sto\sthe\squery\splanner\nand\son\sthe\sresult\sof\ssqlite3WhereOkOnePass(). -D 2015-09-28T17:05:22.174 +C Avoid\sunnecessary\scursors\sand\sseeking\swhen\srunning\sa\sDELETE\sagainst\sa\nWITHOUT\sROWID\stable. +D 2015-09-28T23:45:19.527 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2143eeef6d0cc26006ae5fc4bb242a4a8b973412 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -291,7 +291,7 @@ F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 5a0b735dc95604766f5dac73973658eef782ee8b F src/date.c fb1c99172017dcc8e237339132c91a21a0788584 F src/dbstat.c e637e7a7ff40ef32132a418c6fdf1cfb63aa27c7 -F src/delete.c 371df4fc86e96efeaed3d37565aef77f956be109 +F src/delete.c 514980fc1e6465e906ee7def3dfb70196e4c3aba F src/expr.c 3a76afcdac925294c39903b7002ddb9e5fd29863 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 83e1baba999bed3144ea5a2143fc922edf51135f @@ -300,7 +300,7 @@ F src/global.c 508e4087f7b41d688e4762dcf4d4fe28cfbc87f9 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c 9748a37e058256eb2ead69f028ab85ebf203ad15 +F src/insert.c d0f8d6d6baaec0492ba396aa4a455eb42cb01554 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e F src/lempar.c d344a95d60c24e2f490ee59db9784b1b17439012 @@ -345,7 +345,7 @@ F src/shell.c a11b20da4c6630e0e8f83c47ce36f717dd0422f0 F src/sqlite.h.in 02f6ed7de3a96d10bd1e6e5803e4e4b786dff014 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 64350bf36833a56ad675e27392a913f417c5c308 -F src/sqliteInt.h 5afc6e50402be1e0a870f28e1cd8b32eb9db590f +F src/sqliteInt.h 9773cdb949ec8c3ac71d04e25e63458389e8c3d1 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179 F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e @@ -417,8 +417,8 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c 18b0ed49830cf04fe2d68224b41838a73ac6cd24 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba -F src/where.c 25d7527226d63176b3cd4880a85119cda9f83844 -F src/whereInt.h 7892bb54cf9ca0ae5c7e6094491b94c9286dc647 +F src/where.c e779853aa40a6cdec7fadd026b17c0a98d3298a6 +F src/whereInt.h d7337103c9d40a66ca82ede8646a34fa2e544143 F src/wherecode.c 7660e1ad16817a921b099af553f3e1349352d16f F src/whereexpr.c 2473e4350e30f9b55d1c6a8f66ca23c689f23f1d F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1388,7 +1388,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 5c14d447055bb337428eb1fe0a2934abee381829 -R afaa284829583439d3c828667e0babfd +P c5566bb39c8d9b58f77380b81a873429575c7d5c +R 4e9ae99d481eaf33b22cedef90accac5 +T *branch * delete-without-rowid-opt +T *sym-delete-without-rowid-opt * +T -sym-trunk * U drh -Z 4d08d7f777c595957317ee86b8c88bc8 +Z f54d92c69fd86d18a737b52719ac709a diff --git a/manifest.uuid b/manifest.uuid index 544e794a7a..67a101801f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c5566bb39c8d9b58f77380b81a873429575c7d5c \ No newline at end of file +70ec88b29982f1a2437239ad4d3a9bf39bcc2a60 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index c387c20bef..6de2a754e9 100644 --- a/src/delete.c +++ b/src/delete.c @@ -434,9 +434,8 @@ void sqlite3DeleteFrom( } if( eOnePass!=ONEPASS_OFF ){ - /* For ONEPASS, no need to store the rowid/primary-key. There is only - ** one, so just keep it in its register(s) and fall through to the - ** delete code. */ + /* For ONEPASS, no need to store the rowid/primary-key because rows + ** are deleted as they are discovered */ nKey = nPk; /* OP_Found will use an unpacked key */ aToOpen = sqlite3DbMallocRaw(db, nIdx+2); if( aToOpen==0 ){ @@ -449,6 +448,8 @@ void sqlite3DeleteFrom( if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iTabCur] = 0; if( addrEphOpen ) sqlite3VdbeChangeToNoop(v, addrEphOpen); }else{ + /* For non-ONEPASS, remember the rowid/primary-key of the row to + ** be deleted */ if( pPk ){ /* Add the PK key for this row to the temporary table */ iKey = ++pParse->nMem; @@ -522,6 +523,9 @@ void sqlite3DeleteFrom( { int count = (pParse->nested==0); /* True to count changes */ int iIdxNoSeek = -1; + if( eOnePass!=ONEPASS_OFF ){ + sqlite3WhereHenceforthUseTableCursor(pWInfo, sqlite3VdbeCurrentAddr(v)); + } if( bComplex==0 && aiCurOnePass[1]!=iDataCur ){ iIdxNoSeek = aiCurOnePass[1]; } diff --git a/src/insert.c b/src/insert.c index 53b429c1f4..a4268a82fd 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1680,8 +1680,12 @@ int sqlite3OpenTableAndIndices( for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ int iIdxCur = iBase++; assert( pIdx->pSchema==pTab->pSchema ); - if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) && piDataCur ){ - *piDataCur = iIdxCur; + if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ + if( aToOpen && aToOpen[0]==0 ){ + iIdxCur = iDataCur; + aToOpen[i+1] = 0; + } + if( piDataCur ) *piDataCur = iIdxCur; } if( aToOpen==0 || aToOpen[i+1] ){ sqlite3VdbeAddOp3(v, op, iIdxCur, pIdx->tnum, iDb); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 747f19b39a..6da7bbff3b 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3374,6 +3374,7 @@ void sqlite3DeleteFrom(Parse*, SrcList*, Expr*); void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int); WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int); void sqlite3WhereEnd(WhereInfo*); +void sqlite3WhereHenceforthUseTableCursor(WhereInfo*,int addr); u64 sqlite3WhereOutputRowCount(WhereInfo*); int sqlite3WhereIsDistinct(WhereInfo*); int sqlite3WhereIsOrdered(WhereInfo*); diff --git a/src/where.c b/src/where.c index e224d40b1e..54c4380504 100644 --- a/src/where.c +++ b/src/where.c @@ -27,6 +27,18 @@ static int whereLoopResize(sqlite3*, WhereLoop*, int); /***/ int sqlite3WhereTrace = 0; #endif +/* +** When generating the end-of-WHERE-loop, do not transform references to +** the main table into references to the index after this address. +** +** This interface is invoked by DELETE at a point after when the +** table cursor is pointing to the correct address but before any +** of the index cursors have been deleted. +*/ +void sqlite3WhereHenceforthUseTableCursor(WhereInfo *pWInfo, int addr){ + pWInfo->addrUseTabCur = addr; +} + /* ** Return the estimated number of output rows from a WHERE clause @@ -4538,10 +4550,13 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ pIdx = pLevel->u.pCovidx; } if( pIdx - && (pWInfo->eOnePass==ONEPASS_OFF || !HasRowid(pIdx->pTable)) && !db->mallocFailed ){ - last = sqlite3VdbeCurrentAddr(v); + if( pWInfo->addrUseTabCur ){ + last = pWInfo->addrUseTabCur; + }else{ + last = sqlite3VdbeCurrentAddr(v); + } k = pLevel->addrBody; pOp = sqlite3VdbeGetOp(v, k); for(; knQueryLoop outside the WHERE loop */ int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */ WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */