]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add the SQLITE_ANALYZE_LIMIT compile-time option (expected to be temporary)
authordrh <drh@noemail.net>
Wed, 18 Mar 2020 14:43:05 +0000 (14:43 +0000)
committerdrh <drh@noemail.net>
Wed, 18 Mar 2020 14:43:05 +0000 (14:43 +0000)
that sets a threshold at which ANALYZE starts to use approximations during
the analysis process.

FossilOrigin-Name: a773fd4698d474fda5e57bc77ed66a79cf74efee2706f43f6def6f450bfd1fc0

manifest
manifest.uuid
src/analyze.c

index 0d201b4bd753a14575eeb57a56f4be10db47ce6a..411043d48a11c223820a0102226bbf689667e4a2 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Provide\san\sestimated\srow\scount\sto\sstat_init()\sfor\sSTAT1\sanalysis.
-D 2020-03-17T17:11:23.756
+C Add\sthe\sSQLITE_ANALYZE_LIMIT\scompile-time\soption\s(expected\sto\sbe\stemporary)\nthat\ssets\sa\sthreshold\sat\swhich\sANALYZE\sstarts\sto\suse\sapproximations\sduring\nthe\sanalysis\sprocess.
+D 2020-03-18T14:43:05.229
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -466,7 +466,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
 F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
 F src/alter.c f48a4423c8f198d7f1ae4940f74b606707d05384ac79fb219be8e3323af2a2de
-F src/analyze.c 0df49eed25e472ef00bfe12184548a5a51890e7cd650c40fe2681430bdcae9d1
+F src/analyze.c 2ae3d2e13387eac29ffb4f94279e00ec1f96145f56a06a8aa57533bd0c64bd99
 F src/attach.c fa5addce233a2bb2dfdefeee3b37000e154c47214d3269cab1bb331416e330db
 F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06
 F src/backup.c 5e617c087f1c2d6005c2ec694ce80d6e16bc68d906e1b1c556d7c7c2228b636b
@@ -1860,7 +1860,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 a9bfa47aeea27e91611ba913d33e6635d2016e2c2ab78f9b0657f1bd8933e1a8
-R 83170381358df6124fa4b6f4f7b0bc2e
+P 714419fe85cfdad22979183a94e4569c87740652758ab76b646753cf2b013b54
+R 9e076c207b1e065d9ce5cb1bfdf9885a
 U drh
-Z b22aba55e2c8d6bfe6ccc85eac867e5f
+Z 74d44bcaa72564678d221e098ce4dbd2
index 73b2e21252d9823a5e4236948d94be7333f91ad0..df0df117b5f48888cb9a83f9cb9287227bdaacb7 100644 (file)
@@ -1 +1 @@
-714419fe85cfdad22979183a94e4569c87740652758ab76b646753cf2b013b54
\ No newline at end of file
+a773fd4698d474fda5e57bc77ed66a79cf74efee2706f43f6def6f450bfd1fc0
\ No newline at end of file
index a7f70102b1ff00c3eaa9547e89dbd6958f9d25b3..7290deae19cce5cbd7143bd38181504294648ae3 100644 (file)
@@ -284,6 +284,7 @@ struct StatAccum {
   tRowcnt nRow;             /* Number of rows visited so far */
   int nCol;                 /* Number of columns in index + pk/rowid */
   int nKeyCol;              /* Number of index columns w/o the pk/rowid */
+  u8 nSkipAhead;            /* Number of times of skip-ahead */
   StatSample current;       /* Current row as a StatSample */
 #ifdef SQLITE_ENABLE_STAT4
   tRowcnt nPSample;         /* How often to do a periodic sample */
@@ -404,10 +405,10 @@ static void statInit(
   int nKeyCol;                    /* Number of key columns */
   int nColUp;                     /* nCol rounded up for alignment */
   int n;                          /* Bytes of space to allocate */
-  sqlite3 *db;                    /* Database connection */
+  sqlite3 *db = sqlite3_context_db_handle(context);   /* Database connection */
 #ifdef SQLITE_ENABLE_STAT4
   /* Maximum number of samples.  0 if STAT4 data is not collected */
-  int mxSample = sqlite3_value_int64(argv[2]) ? SQLITE_STAT4_SAMPLES : 0;
+  int mxSample = OptimizationEnabled(db,SQLITE_Stat4) ?SQLITE_STAT4_SAMPLES :0;
 #endif
 
   /* Decode the three function arguments */
@@ -442,16 +443,17 @@ static void statInit(
   p->nRow = 0;
   p->nCol = nCol;
   p->nKeyCol = nKeyCol;
+  p->nSkipAhead = 0;
   p->current.anDLt = (tRowcnt*)&p[1];
   p->current.anEq = &p->current.anDLt[nColUp];
 
 #ifdef SQLITE_ENABLE_STAT4
+  p->mxSample = mxSample;
   if( mxSample ){
     u8 *pSpace;                     /* Allocated space not yet assigned */
     int i;                          /* Used to iterate through p->aSample[] */
 
     p->iGet = -1;
-    p->mxSample = mxSample;
     p->nPSample = (tRowcnt)(p->nEst/(mxSample/3+1) + 1);
     p->current.anLt = &p->current.anEq[nColUp];
     p->iPrn = 0x689e962d*(u32)nCol ^ 0xd0944565*(u32)sqlite3_value_int(argv[2]);
@@ -675,6 +677,15 @@ static void samplePushPrevious(StatAccum *p, int iChng){
 }
 #endif /* SQLITE_ENABLE_STAT4 */
 
+/*
+** A limit on the number of rows of an index that will be examined
+** by ANALYZE before it starts going with approximations.  Zero means
+** "no limit".
+*/
+#ifndef SQLITE_ANALYZE_LIMIT
+# define SQLITE_ANALYZE_LIMIT 0
+#endif
+
 /*
 ** Implementation of the stat_push SQL function:  stat_push(P,C,R)
 ** Arguments:
@@ -684,10 +695,13 @@ static void samplePushPrevious(StatAccum *p, int iChng){
 **    R     Rowid for the current row.  Might be a key record for
 **          WITHOUT ROWID tables.
 **
-** This SQL function always returns NULL.  It's purpose it to accumulate
-** statistical data and/or samples in the StatAccum object about the
-** index being analyzed.  The stat_get() SQL function will later be used to
-** extract relevant information for constructing the sqlite_statN tables.
+** The purpose of this routine is to collect statistical data and/or
+** samples from the index being analyzed into the StatAccum object.
+** The stat_get() SQL function will be used afterwards to
+** retrieve the information gathered.
+**
+** This SQL function usually returns NULL, but might return an integer
+** if it wants the byte-code to do special processing.
 **
 ** The R parameter is only used for STAT4
 */
@@ -729,6 +743,7 @@ static void statPush(
       p->current.anEq[i] = 1;
     }
   }
+
   p->nRow++;
 #ifdef SQLITE_ENABLE_STAT4
   if( p->mxSample ){
@@ -757,9 +772,16 @@ static void statPush(
         sampleCopy(p, &p->aBest[i], &p->current);
       }
     }
+  }else
+#endif
+#if SQLITE_ANALYZE_LIMIT
+  if( p->nRow>SQLITE_ANALYZE_LIMIT*(p->nSkipAhead+1) ){
+    p->nSkipAhead++;
+    sqlite3_result_int(context, p->current.anDLt[0]>0);
   }
 #endif
 }
+
 static const FuncDef statPushFuncdef = {
   2+IsStat4,       /* nArg */
   SQLITE_UTF8,     /* funcFlags */
@@ -847,7 +869,8 @@ static void statGet(
       return;
     }
 
-    sqlite3_snprintf(24, zRet, "%llu", (u64)p->nRow);
+    sqlite3_snprintf(24, zRet, "%llu", 
+        p->nSkipAhead ? (u64)p->nEst : (u64)p->nRow);
     z = zRet + sqlite3Strlen30(zRet);
     for(i=0; i<p->nKeyCol; i++){
       u64 nDistinct = p->current.anDLt[i] + 1;
@@ -1204,9 +1227,18 @@ static void analyzeOneTable(
     }
 #endif
     assert( regChng==(regStat+1) );
-    sqlite3VdbeAddFunctionCall(pParse, 1, regStat, regTemp, 2+IsStat4,
-                               &statPushFuncdef, 0);
-    sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
+    {
+      int j1, j2, j3;
+      sqlite3VdbeAddFunctionCall(pParse, 1, regStat, regTemp, 2+IsStat4,
+                                 &statPushFuncdef, 0);
+      j1 = sqlite3VdbeAddOp1(v, OP_IsNull, regTemp);
+      j2 = sqlite3VdbeAddOp1(v, OP_If, regTemp);
+      j3 = sqlite3VdbeAddOp4Int(v, OP_SeekGT, iIdxCur, 0, regPrev, 1);
+      sqlite3VdbeJumpHere(v, j1);
+      sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
+      sqlite3VdbeJumpHere(v, j2);
+      sqlite3VdbeJumpHere(v, j3);
+    }
 
     /* Add the entry to the stat1 table. */
     callStatGet(pParse, regStat, STAT_GET_STAT1, regStat1);