]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Compute the bitmask of indexed columns for each index once when the Index
authordrh <drh@noemail.net>
Sat, 9 Jun 2018 01:12:08 +0000 (01:12 +0000)
committerdrh <drh@noemail.net>
Sat, 9 Jun 2018 01:12:08 +0000 (01:12 +0000)
objecct is constructed, instead of recomputing it every time it is needed.

FossilOrigin-Name: d735872ec383bbd220b08c61d25db9ff3675d2542b9e7867e7d6323a12e0cc23

manifest
manifest.uuid
src/build.c
src/sqliteInt.h
src/where.c

index 4a1d9dc884ae9c5053e6c93d13f008d99431a7e1..310f7a57fb3241f020328e1db39ce7f70c862eb1 100644 (file)
--- 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
index 5cb8cc61927bc68d9b1371806be9964769ad639e..dd0ca06fe8526bdbee1c5149b35ec66b9302b890 100644 (file)
@@ -1 +1 @@
-292724ffc4bfca435fff309383d488ffdbe1e314e5eb26da21cf2f621b64bce5
\ No newline at end of file
+d735872ec383bbd220b08c61d25db9ff3675d2542b9e7867e7d6323a12e0cc23
\ No newline at end of file
index 3d982f72ea596d2427c586e9b54b65717eef92bd..44fc4573b28a419a2909e6bac44815645ee4a447 100644 (file)
@@ -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( x<BMS-1 ) m |= MASKBIT(x);
+    }
+  }
+  pIdx->colNotIdxed = ~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; j<pTab->nCol; j++){
index 91fde727a2b9ebdbf1a4870c9829bcf4ce9afea6..98bd7e407908be954a91634693b479b40731f1cb 100644 (file)
@@ -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
index 7aba0eb5dc7aa9a0fa76de53d24f8680f6b601a1..56d37be01224a8a55b49e4fd9fb76445a2256cf1 100644 (file)
@@ -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( x<BMS-1 ) m |= MASKBIT(x);
-    }
-  }
-  return m;
-}
-
 /* Check to see if a partial index with pPartIndexWhere can be used
 ** in the current query.  Return true if it can be and false if not.
 */
@@ -2967,7 +2949,7 @@ static int whereLoopAddBtree(
         pNew->wsFlags = 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;