From: danielk1977 Date: Thu, 29 Nov 2007 17:43:27 +0000 (+0000) Subject: When using an index to scan a database table, read column data from the index in... X-Git-Tag: version-3.6.10~1597 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=21de2e755c4645778bd4e53b252909272b2c491a;p=thirdparty%2Fsqlite.git When using an index to scan a database table, read column data from the index in preference to the table. This increases the likelihood that the table will not be required at all. (CVS 4580) FossilOrigin-Name: 061608c72ac0a96eacf3b64d638235e4739f96ba --- diff --git a/manifest b/manifest index 6b48852469..951efb8f45 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Optimisations\sfor\sexpressions\sof\sthe\sform\s"\sIN\s(SELECT\s\sFROM\s)".\s(CVS\s4579) -D 2007-11-29T17:05:18 +C When\susing\san\sindex\sto\sscan\sa\sdatabase\stable,\sread\scolumn\sdata\sfrom\sthe\sindex\sin\spreference\sto\sthe\stable.\sThis\sincreases\sthe\slikelihood\sthat\sthe\stable\swill\snot\sbe\srequired\sat\sall.\s(CVS\s4580) +D 2007-11-29T17:43:28 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7 F Makefile.in 35396fd58890420b29edcf27b6c0e2d054862a6b F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -176,7 +176,7 @@ F src/vdbeblob.c 82f51cdf9b0c0af729732fde48c824e498c0a1ca F src/vdbefifo.c 334c838c8f42d61a94813d136019ee566b5dc2f6 F src/vdbemem.c 123994fcd344993d2fb050a83b91b341bbbd08b4 F src/vtab.c f819d55ef638d45e09ce00009d435da8bf16f528 -F src/where.c a03cd9da865f9ae9d750b01b45ad0bd82bd456f1 +F src/where.c 7ec7c7a5b3a534d5ccbe9d73690b8969ee6b3f08 F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/all.test ee350b9ab15b175fc0a8fb51bf2141ed3a3b9cba @@ -336,7 +336,7 @@ F test/insert3.test 9a4ef3526fd3cca8b05278020ec3100448b4c677 F test/insert4.test 6919ddacd79c2cfeb9785b0f84217f9cb14853b5 F test/insert5.test e8d5ba31283db5b0315ada9774dd99b6e9fe2122 F test/interrupt.test 81555fb0f8179bb2d0dc7151fd75428223f93cf2 -F test/intpkey.test af4fd826c4784ec5c93b444de07adea0254d0d30 +F test/intpkey.test 537669fd535f62632ca64828e435b9e54e8d677f F test/io.test 80a7a7f1a2792e037d447b03e8c22ee1f6eaf339 F test/ioerr.test ae429185a3a11a318aa7ec64e2188e6119e43bca F test/ioerr2.test e3d52c40f43f9b61da9b38951a737e7b84ebae96 @@ -509,7 +509,7 @@ F test/vtabA.test 9cb6b1afead6fdd91bbdf1ca65c44ccfd9b10936 F test/vtab_alter.test b0c0f61a9588b509c2ba20dedc2db04999da6656 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8 F test/vtab_shared.test d631d1f820c38c18939d53aab1fc35db5f0a8094 -F test/where.test 1bcde8984c63747ac6d6bafcacd20fd6e8a223de +F test/where.test 5ff4a1bda6352b73354faf1a97706bbfa0d47dfe F test/where2.test 9bbf1cc675730954047d663e4c0dc5d4c9669ca4 F test/where3.test 0a30fe9808b0fa01c46d0fcf4fac0bf6cf75bb30 F test/where4.test 1b1cd72d5f205ce34d5a31f3c4918f833e5e6a63 @@ -594,7 +594,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P 221aee72be040769e8026b91648f03c6366a8821 -R 17bc1550023a2d1b2bcf36adaf1ceda3 +P 56d0e32677744df8570b519fae1c04da4ea4984d +R 36e691e0ba7fd3d68c366765c689ffb2 U danielk1977 -Z 90a3ecb3d9566cd903183cf31905697c +Z 64a9f02b9181db1b1e3b35c33464441d diff --git a/manifest.uuid b/manifest.uuid index 9c13383ea2..6cdf0ba1b7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -56d0e32677744df8570b519fae1c04da4ea4984d \ No newline at end of file +061608c72ac0a96eacf3b64d638235e4739f96ba \ No newline at end of file diff --git a/src/where.c b/src/where.c index 853af403ff..2e39b03137 100644 --- a/src/where.c +++ b/src/where.c @@ -16,7 +16,7 @@ ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** -** $Id: where.c,v 1.264 2007/11/29 17:05:18 danielk1977 Exp $ +** $Id: where.c,v 1.265 2007/11/29 17:43:28 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -2215,10 +2215,6 @@ WhereInfo *sqlite3WhereBegin( VdbeComment((v, "# %s", pIx->zName)); sqlite3VdbeOp3(v, OP_OpenRead, iIdxCur, pIx->tnum, (char*)pKey, P3_KEYINFO_HANDOFF); - } - if( (pLevel->flags & (WHERE_IDX_ONLY|WHERE_COLUMN_RANGE))!=0 ){ - /* Only call OP_SetNumColumns on the index if we might later use - ** OP_Column on the index. */ sqlite3VdbeAddOp(v, OP_SetNumColumns, iIdxCur, pIx->nColumn+1); } sqlite3CodeVerifySchema(pParse, iDb); @@ -2742,8 +2738,12 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ sqlite3VdbeAddOp(v, OP_Close, pLevel->iIdxCur, 0); } - /* Make cursor substitutions for cases where we want to use - ** just the index and never reference the table. + /* If this scan uses an index, make code substitutions to read data + ** from the index in preference to the table. Sometimes, this means + ** the table need never be read from. This is a performance boost, + ** as the vdbe level waits until the table is read before actually + ** seeking the table cursor to the record corresponding to the current + ** position in the index. ** ** Calls to the code generator in between sqlite3WhereBegin and ** sqlite3WhereEnd will have created code that references the table @@ -2751,10 +2751,11 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ ** that reference the table and converts them into opcodes that ** reference the index. */ - if( pLevel->flags & WHERE_IDX_ONLY ){ + if( pLevel->pIdx ){ int k, j, last; VdbeOp *pOp; Index *pIdx = pLevel->pIdx; + int useIndexOnly = pLevel->flags & WHERE_IDX_ONLY; assert( pIdx!=0 ); pOp = sqlite3VdbeGetOp(v, pWInfo->iTop); @@ -2762,17 +2763,18 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ for(k=pWInfo->iTop; kp1!=pLevel->iTabCur ) continue; if( pOp->opcode==OP_Column ){ - pOp->p1 = pLevel->iIdxCur; for(j=0; jnColumn; j++){ if( pOp->p2==pIdx->aiColumn[j] ){ pOp->p2 = j; + pOp->p1 = pLevel->iIdxCur; break; } } + assert(!useIndexOnly || jnColumn); }else if( pOp->opcode==OP_Rowid ){ pOp->p1 = pLevel->iIdxCur; pOp->opcode = OP_IdxRowid; - }else if( pOp->opcode==OP_NullRow ){ + }else if( pOp->opcode==OP_NullRow && useIndexOnly ){ pOp->opcode = OP_Noop; } } diff --git a/test/intpkey.test b/test/intpkey.test index 168f1df5c5..05b6cdf04c 100644 --- a/test/intpkey.test +++ b/test/intpkey.test @@ -13,7 +13,7 @@ # This file implements tests for the special processing associated # with INTEGER PRIMARY KEY columns. # -# $Id: intpkey.test,v 1.23 2005/07/21 03:48:20 drh Exp $ +# $Id: intpkey.test,v 1.24 2007/11/29 17:43:28 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -293,7 +293,7 @@ do_test intpkey-3.8 { count { SELECT * FROM t1 WHERE c=='world' AND a>7; } -} {11 hello world 5} +} {11 hello world 4} do_test intpkey-3.9 { count { SELECT * FROM t1 WHERE 7