From: drh Date: Sat, 9 Jun 2018 01:12:08 +0000 (+0000) Subject: Compute the bitmask of indexed columns for each index once when the Index X-Git-Tag: version-3.25.0~203 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1fe3ac73474a71583b9bd05a5e9016855748c0b3;p=thirdparty%2Fsqlite.git Compute the bitmask of indexed columns for each index once when the Index objecct is constructed, instead of recomputing it every time it is needed. FossilOrigin-Name: d735872ec383bbd220b08c61d25db9ff3675d2542b9e7867e7d6323a12e0cc23 --- diff --git a/manifest b/manifest index 4a1d9dc884..310f7a57fb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sinvoking\sthe\swhereLoopAddOr()\sroutine\sin\sthe\squery\splanner\sif\sthere\nare\sno\sOR\soperators\sin\sthe\sWHERE\sclause,\sthus\sspeeding\sup\squery\splanning\nslightly. -D 2018-06-09T00:09:58.256 +C Compute\sthe\sbitmask\sof\sindexed\scolumns\sfor\seach\sindex\sonce\swhen\sthe\sIndex\nobjecct\sis\sconstructed,\sinstead\sof\srecomputing\sit\severy\stime\sit\sis\sneeded. +D 2018-06-09T01:12:08.387 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da @@ -439,7 +439,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 06690f5ad144c5e69dfb68d5ec8ee4819c6d40f4b8bc77aa97975938f59d928c F src/btree.h ab639c4b9b210b8f4cd7a3a922af73df9a3f27c1d124267339fd73ef8619f488 F src/btreeInt.h 620ab4c7235f43572cf3ac2ac8723cbdf68073be4d29da24897c7b77dda5fd96 -F src/build.c 5fc41458505331bfb0c175f40b9a13cb335f826bed3ae311aaae000c132d7b16 +F src/build.c 3b3bfa88800739e1f11313dcecfba5ef8e4757b6c929cdf7de9fcfc01002b81f F src/callback.c 36caff1e7eb7deb58572d59c41cee8f064a11d00297616995c5050ea0cfc1288 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 849d4cebe008cfc6e4799b034a172b4eaf8856b100739632a852732ba66eee48 @@ -500,7 +500,7 @@ F src/shell.c.in 4d0ddf10c403710d241bf920163dcf032c21119aebb61e70840942c0eafecdf F src/sqlite.h.in 63b07f76731f2b1e55c48fdb9f0508dcc6fbe3971010b8612ffd847c3c56d9a1 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9887b27e69c01e79c2cbe74ef73bf01af5b5703d6a7f0a4371e386d7249cb1c7 -F src/sqliteInt.h d2bd297dba08f2390a91c31ff775e0964e9663df5b2910a569fe6f830b8b2beb +F src/sqliteInt.h 9332b820382288dde7d6ea712bbcd34380bbbeb44f6f7032710bd5240fd4067d F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -579,7 +579,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c aa9cffc7a2bad6b826a86c8562dd4978398720ed41cb8ee7aa9d054eb8b456a0 F src/wal.h 8de5d2d3de0956d6f6cb48c83a4012d5f227b8fe940f3a349a4b7e85ebcb492a F src/walker.c da987a20d40145c0a03c07d8fefcb2ed363becc7680d0500d9c79915591f5b1f -F src/where.c b93db8c543ce60bdeb325250665e8fb5374c02b31d581c339ae8723da9b7f889 +F src/where.c 9915929594a8c6bf8ca8d6e02a4f7e632948fa523712ab647490d18855a43656 F src/whereInt.h 09dbf692741bb5ac4f4ce15e3e124bcff3c1077dd39afd2aa7ef573040252c11 F src/wherecode.c 3317f2b083a66d3e65a03edf316ade4ccb0a99c9956273282ebb579b95d4ba96 F src/whereexpr.c d979cd594c9abbf038b8671a9b05f1e9d02300b06f987f2ea2c06712c60b8077 @@ -1731,7 +1731,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2cbbabdf5ef624d809fbb40d2d312a29e0b5f02756fc0dbf6985fc8b0c8d1ade -R 0b684b2e3c17dc858ffe6bf2e9f152c7 +P 292724ffc4bfca435fff309383d488ffdbe1e314e5eb26da21cf2f621b64bce5 +R 84501035b6f16659219d9bb1862a6d24 U drh -Z 039981a09de1ec68f373ff429bf5bde6 +Z ca51630bcd989bed6d96c283f487ffd2 diff --git a/manifest.uuid b/manifest.uuid index 5cb8cc6192..dd0ca06fe8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -292724ffc4bfca435fff309383d488ffdbe1e314e5eb26da21cf2f621b64bce5 \ No newline at end of file +d735872ec383bbd220b08c61d25db9ff3675d2542b9e7867e7d6323a12e0cc23 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 3d982f72ea..44fc4573b2 100644 --- a/src/build.c +++ b/src/build.c @@ -1695,6 +1695,31 @@ static int hasColumn(const i16 *aiCol, int nCol, int x){ return 0; } +/* Recompute the colNotIdxed field of the Index. +** +** colNotIdxed is a bitmask that has a 0 bit representing each indexed +** columns that are within the first 63 columns of the table. The +** high-order bit of colNotIdxed is always 1. All unindexed columns +** of the table have a 1. +** +** The colNotIdxed mask is AND-ed with the SrcList.a[].colUsed mask +** to determine if the index is covering index. +*/ +static void recomputeColumnsNotIndexed(Index *pIdx){ + Bitmask m = 0; + int j; + for(j=pIdx->nColumn-1; j>=0; j--){ + int x = pIdx->aiColumn[j]; + if( x>=0 ){ + testcase( x==BMS-1 ); + testcase( x==BMS-2 ); + if( xcolNotIdxed = ~m; + assert( (pIdx->colNotIdxed>>63)==1 ); +} + /* ** This routine runs at the end of parsing a CREATE TABLE statement that ** has a WITHOUT ROWID clause. The job of this routine is to convert both @@ -1843,6 +1868,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ }else{ pPk->nColumn = pTab->nCol; } + recomputeColumnsNotIndexed(pPk); } /* @@ -3276,6 +3302,7 @@ void sqlite3CreateIndex( ** it as a covering index */ assert( HasRowid(pTab) || pTab->iPKey<0 || sqlite3ColumnOfIndex(pIndex, pTab->iPKey)>=0 ); + recomputeColumnsNotIndexed(pIndex); if( pTblName!=0 && pIndex->nColumn>=pTab->nCol ){ pIndex->isCovering = 1; for(j=0; jnCol; j++){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 91fde727a2..98bd7e4079 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1109,6 +1109,32 @@ typedef struct Walker Walker; typedef struct WhereInfo WhereInfo; typedef struct With With; + +/* +** The bitmask datatype defined below is used for various optimizations. +** +** Changing this from a 64-bit to a 32-bit type limits the number of +** tables in a join to 32 instead of 64. But it also reduces the size +** of the library by 738 bytes on ix86. +*/ +#ifdef SQLITE_BITMASK_TYPE + typedef SQLITE_BITMASK_TYPE Bitmask; +#else + typedef u64 Bitmask; +#endif + +/* +** The number of bits in a Bitmask. "BMS" means "BitMask Size". +*/ +#define BMS ((int)(sizeof(Bitmask)*8)) + +/* +** A bit in a Bitmask +*/ +#define MASKBIT(n) (((Bitmask)1)<<(n)) +#define MASKBIT32(n) (((unsigned int)1)<<(n)) +#define ALLBITS ((Bitmask)-1) + /* A VList object records a mapping between parameters/variables/wildcards ** in the SQL statement (such as $abc, @pqr, or :xyz) and the integer ** variable number associated with that parameter. See the format description @@ -2198,6 +2224,7 @@ struct Index { tRowcnt *aiRowEst; /* Non-logarithmic stat1 data for this index */ tRowcnt nRowEst0; /* Non-logarithmic number of rows in the index */ #endif + Bitmask colNotIdxed; /* 0 for unindexed columns in pTab */ }; /* @@ -2543,31 +2570,6 @@ struct IdList { int nId; /* Number of identifiers on the list */ }; -/* -** The bitmask datatype defined below is used for various optimizations. -** -** Changing this from a 64-bit to a 32-bit type limits the number of -** tables in a join to 32 instead of 64. But it also reduces the size -** of the library by 738 bytes on ix86. -*/ -#ifdef SQLITE_BITMASK_TYPE - typedef SQLITE_BITMASK_TYPE Bitmask; -#else - typedef u64 Bitmask; -#endif - -/* -** The number of bits in a Bitmask. "BMS" means "BitMask Size". -*/ -#define BMS ((int)(sizeof(Bitmask)*8)) - -/* -** A bit in a Bitmask -*/ -#define MASKBIT(n) (((Bitmask)1)<<(n)) -#define MASKBIT32(n) (((unsigned int)1)<<(n)) -#define ALLBITS ((Bitmask)-1) - /* ** The following structure describes the FROM clause of a SELECT statement. ** Each table or subquery in the FROM clause is a separate element of diff --git a/src/where.c b/src/where.c index 7aba0eb5dc..56d37be012 100644 --- a/src/where.c +++ b/src/where.c @@ -2734,24 +2734,6 @@ static int indexMightHelpWithOrderBy( return 0; } -/* -** Return a bitmask where 1s indicate that the corresponding column of -** the table is used by an index. Only the first 63 columns are considered. -*/ -static Bitmask columnsInIndex(Index *pIdx){ - Bitmask m = 0; - int j; - for(j=pIdx->nColumn-1; j>=0; j--){ - int x = pIdx->aiColumn[j]; - if( x>=0 ){ - testcase( x==BMS-1 ); - testcase( x==BMS-2 ); - if( xwsFlags = WHERE_IDX_ONLY | WHERE_INDEXED; m = 0; }else{ - m = pSrc->colUsed & ~columnsInIndex(pProbe); + m = pSrc->colUsed & pProbe->colNotIdxed; pNew->wsFlags = (m==0) ? (WHERE_IDX_ONLY|WHERE_INDEXED) : WHERE_INDEXED; } @@ -4370,7 +4352,7 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){ } if( j!=pIdx->nKeyCol ) continue; pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_ONEROW|WHERE_INDEXED; - if( pIdx->isCovering || (pItem->colUsed & ~columnsInIndex(pIdx))==0 ){ + if( pIdx->isCovering || (pItem->colUsed & pIdx->colNotIdxed)==0 ){ pLoop->wsFlags |= WHERE_IDX_ONLY; } pLoop->nLTerm = j;