From: drh Date: Wed, 30 May 2018 00:54:23 +0000 (+0000) Subject: Demonstration code on a possible technique for optimizing the use of IN X-Git-Tag: version-3.25.0~207^2~10 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a0368d9396ea3c8cb80f902cacb7594039909bb2;p=thirdparty%2Fsqlite.git Demonstration code on a possible technique for optimizing the use of IN operator on columns to the right of multicolumn indexes. If the OP_Noop generated where were really a new opcode that checked to see if there existed any entries in the index with a matching prefix, it might prevent unnecessary iterations of the IN operator. FossilOrigin-Name: 92f0fe155d5546fc7f4a443d0630613dabe149061966308e5420fad652278f16 --- diff --git a/manifest b/manifest index fad5a45c93..2cfdac9d08 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Increase\sthe\snumber\sof\sdatabase\shandles\sopened\sby\stest\sscript\soserror.test\sto\nprovoke\san\s"out\sof\sfile-descriptors"\serror\sto\s20000\s(from\s2000). -D 2018-05-29T19:12:58.327 +C Demonstration\scode\son\sa\spossible\stechnique\sfor\soptimizing\sthe\suse\sof\sIN\noperator\son\scolumns\sto\sthe\sright\sof\smulticolumn\sindexes.\s\sIf\sthe\sOP_Noop\ngenerated\swhere\swere\sreally\sa\snew\sopcode\sthat\schecked\sto\ssee\sif\sthere\sexisted\nany\sentries\sin\sthe\sindex\swith\sa\smatching\sprefix,\sit\smight\sprevent\sunnecessary\niterations\sof\sthe\sIN\soperator. +D 2018-05-30T00:54:23.670 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da @@ -578,9 +578,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c aa9cffc7a2bad6b826a86c8562dd4978398720ed41cb8ee7aa9d054eb8b456a0 F src/wal.h 8de5d2d3de0956d6f6cb48c83a4012d5f227b8fe940f3a349a4b7e85ebcb492a F src/walker.c da987a20d40145c0a03c07d8fefcb2ed363becc7680d0500d9c79915591f5b1f -F src/where.c 60ec752fcbe9f9e0271ac60548d159a540a1ee47a4f9fedc85e88a3d0e392dd1 -F src/whereInt.h cbae2bcd37cfebdb7812a8b188cdb19634ced2b9346470d1c270556b0c33ea53 -F src/wherecode.c 728c7f70731430ccdac807a79969873e1af6968bf1c4745dff3f9dd35f636cc8 +F src/where.c a9a270991e5e526151d077959b868481b28db8707bc6d29b76badd536c48225a +F src/whereInt.h b6ab96d9c1e48d029eaaee8f9b6d05e6a2405af0ad68f684e75f21c46837ae11 +F src/wherecode.c 49256d67b95187f9b49777c0f526362f4eaaa46850700fe5020cf6b154a2fc52 F src/whereexpr.c e90b2e76dcabc81edff56633bf281bc01d93b71e0c81482dc06925ce39f5844a F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1729,7 +1729,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 89f56d6b0a6847b042a1556cdf79c598c9bfdbdd5f9529d508ca7b4d26a6ed38 -R d1b9772c07cea88c945a7c3a78ab0901 -U dan -Z caf1e7dfd24b3c90db5132889b4bf8f4 +P 3b00f73456c65dfc1827fdada9afb49245f9addfa684d5ae35e69a07f39164bf +R 150e6f6563a2a6ab67c600fc77f11cd6 +T *branch * multikey-opt-idea +T *sym-multikey-opt-idea * +T -sym-trunk * +U drh +Z 0e3a9a98888882656fe85b8d1be89ddd diff --git a/manifest.uuid b/manifest.uuid index 16cd4a0a40..60b47eade3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3b00f73456c65dfc1827fdada9afb49245f9addfa684d5ae35e69a07f39164bf \ No newline at end of file +92f0fe155d5546fc7f4a443d0630613dabe149061966308e5420fad652278f16 \ No newline at end of file diff --git a/src/where.c b/src/where.c index b83915e264..b93e2260e6 100644 --- a/src/where.c +++ b/src/where.c @@ -5083,6 +5083,10 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){ sqlite3VdbeJumpHere(v, pIn->addrInTop+1); if( pIn->eEndLoopOp!=OP_Noop ){ + if( pIn->nPrefix ){ + sqlite3VdbeAddOp3(v, OP_Noop, pLevel->iIdxCur, + pIn->iBase, pIn->nPrefix); + } sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop); VdbeCoverage(v); VdbeCoverageIf(v, pIn->eEndLoopOp==OP_PrevIfOpen); diff --git a/src/whereInt.h b/src/whereInt.h index 4b6213af31..08159fe28e 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -82,6 +82,8 @@ struct WhereLevel { struct InLoop { int iCur; /* The VDBE cursor used by this IN operator */ int addrInTop; /* Top of the IN loop */ + int iBase; /* Base register of multi-key index record */ + int nPrefix; /* Number of prior entires in the key */ u8 eEndLoopOp; /* IN Loop terminator. OP_Next or OP_Prev */ } *aInLoop; /* Information about each nested IN operator */ } in; /* Used when pWLoop->wsFlags&WHERE_IN_ABLE */ diff --git a/src/wherecode.c b/src/wherecode.c index c9edab7b0c..1578122479 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -592,6 +592,8 @@ static int codeEqualityTerm( if( i==iEq ){ pIn->iCur = iTab; pIn->eEndLoopOp = bRev ? OP_PrevIfOpen : OP_NextIfOpen; + pIn->iBase = iReg - i; + pIn->nPrefix = i; }else{ pIn->eEndLoopOp = OP_Noop; }