]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Modify the ANALYZE command to store worst-case statistics in sqlite_stat1,
authordrh <drh@noemail.net>
Mon, 29 Feb 2016 18:30:30 +0000 (18:30 +0000)
committerdrh <drh@noemail.net>
Mon, 29 Feb 2016 18:30:30 +0000 (18:30 +0000)
rather thn average case.

FossilOrigin-Name: 5a0143c94ec0682798f3c09fba63593e695d2e2d

manifest
manifest.uuid
src/analyze.c

index bacddf080cf561dc339bab6bca6e7444a7f21fd0..530227dd4825935bc9a06fb76bdd0227ff60a8cc 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sa\sproblem\sin\sfts5\swhere\sa\scorrupt\sdb\scould\slead\sto\sa\s(huge)\sbuffer\soverread.
-D 2016-02-29T17:34:16.069
+C Modify\sthe\sANALYZE\scommand\sto\sstore\sworst-case\sstatistics\sin\ssqlite_stat1,\nrather\sthn\saverage\scase.
+D 2016-02-29T18:30:30.116
 F Makefile.in 4e90dc1521879022aa9479268a4cd141d1771142
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc 4f319afb7c049d40aff7af6e8c4e7cc2ba18e079
@@ -286,7 +286,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
 F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
 F src/alter.c 44e18dfd78e8942d65d3cdaec4de972b5cd9f1f2
-F src/analyze.c ab57b6763dd4c6170a20673d14882c033affd188
+F src/analyze.c 37343619c6c560722aac521d156d34ebff746526
 F src/attach.c a3724c64de1099d85e30751213d285752aed9505
 F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
 F src/backup.c f60f0aa55d25d853ffde53d0b0370a7bb7ee41ce
@@ -1451,7 +1451,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 251d6473f7c9ad95adbdcc49cb8eaf7c0956764b
-R 1a43d3061a1f154a38fc05ffa17e1f4a
-U dan
-Z 0ef60cd2035dd9bea82e9df13f5bcf57
+P c9a30e117f2c6c9ef0cc0c6ca5227d2961715b8f
+R 180de557065fd2bddac753825b6be69a
+T *branch * analyze-worst-case
+T *sym-analyze-worst-case *
+T -sym-trunk *
+U drh
+Z 3d046dcd3035333c5259dea36a77e4b0
index 2a4a25da5e8ff4680a636bde71ca60bc46aef60f..49afe15d1c07f4ceb6115781975811ced2b80a20 100644 (file)
@@ -1 +1 @@
-c9a30e117f2c6c9ef0cc0c6ca5227d2961715b8f
\ No newline at end of file
+5a0143c94ec0682798f3c09fba63593e695d2e2d
\ No newline at end of file
index cd59ae681dacfeed1924ed282feb529d2ce88a0b..f4c058e23207e0e64a13f88165cbc145cb115a0c 100644 (file)
@@ -267,6 +267,7 @@ typedef struct Stat4Sample Stat4Sample;
 struct Stat4Sample {
   tRowcnt *anEq;                  /* sqlite_stat4.nEq */
   tRowcnt *anDLt;                 /* sqlite_stat4.nDLt */
+  tRowcnt *amxEq;                 /* Maximum length run of equal values */
 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
   tRowcnt *anLt;                  /* sqlite_stat4.nLt */
   union {
@@ -418,8 +419,9 @@ static void statInit(
   /* Allocate the space required for the Stat4Accum object */
   n = sizeof(*p) 
     + sizeof(tRowcnt)*nColUp                  /* Stat4Accum.anEq */
-    + sizeof(tRowcnt)*nColUp                  /* Stat4Accum.anDLt */
+    + sizeof(tRowcnt)*nColUp                  /* Stat4Accum.amxEq */
 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+    + sizeof(tRowcnt)*nColUp                  /* Stat4Accum.anDLt */
     + sizeof(tRowcnt)*nColUp                  /* Stat4Accum.anLt */
     + sizeof(Stat4Sample)*(nCol+mxSample)     /* Stat4Accum.aBest[], a[] */
     + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample)
@@ -436,18 +438,19 @@ static void statInit(
   p->nRow = 0;
   p->nCol = nCol;
   p->nKeyCol = nKeyCol;
-  p->current.anDLt = (tRowcnt*)&p[1];
-  p->current.anEq = &p->current.anDLt[nColUp];
+  p->current.anEq = (tRowcnt*)&p[1];
+  p->current.amxEq = &p->current.anEq[nColUp];
 
 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
   {
     u8 *pSpace;                     /* Allocated space not yet assigned */
-    int i;                          /* Used to iterate through p->aSample[] */
+    int i;                          /* Loop counter */
 
     p->iGet = -1;
     p->mxSample = mxSample;
     p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[2])/(mxSample/3+1) + 1);
-    p->current.anLt = &p->current.anEq[nColUp];
+    p->current.anDLt = &p->current.amxEq[nColUp];
+    p->current.anLt = &p->current.anDLt[nColUp];
     p->iPrn = 0x689e962d*(u32)nCol ^ 0xd0944565*(u32)sqlite3_value_int(argv[2]);
   
     /* Set up the Stat4Accum.a[] and aBest[] arrays */
@@ -721,7 +724,10 @@ static void statPush(
 
   if( p->nRow==0 ){
     /* This is the first call to this function. Do initialization. */
-    for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1;
+    for(i=0; i<p->nCol; i++){
+      p->current.anEq[i] = 1;
+      p->current.amxEq[i] = 1;
+    }
   }else{
     /* Second and subsequent calls get processed here */
     samplePushPrevious(p, iChng);
@@ -729,11 +735,12 @@ static void statPush(
     /* Update anDLt[], anLt[] and anEq[] to reflect the values that apply
     ** to the current row of the index. */
     for(i=0; i<iChng; i++){
+      if( p->current.amxEq[i]==p->current.anEq[i] ) p->current.amxEq[i]++;
       p->current.anEq[i]++;
     }
     for(i=iChng; i<p->nCol; i++){
-      p->current.anDLt[i]++;
 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+      p->current.anDLt[i]++;
       p->current.anLt[i] += p->current.anEq[i];
 #endif
       p->current.anEq[i] = 1;
@@ -828,7 +835,7 @@ static void statGet(
     ** the index. The first integer in the list is the total number of 
     ** entries in the index. There is one additional integer in the list 
     ** for each indexed column. This additional integer is an estimate of
-    ** the number of rows matched by a stabbing query on the index using
+    ** the number of rows matched by a query on the index using
     ** a key with the corresponding number of fields. In other words,
     ** if the index is on columns (a,b) and the sqlite_stat1 value is 
     ** "100 10 2", then SQLite estimates that:
@@ -837,10 +844,8 @@ static void statGet(
     **   * "WHERE a=?" matches 10 rows, and
     **   * "WHERE a=? AND b=?" matches 2 rows.
     **
-    ** If D is the count of distinct values and K is the total number of 
-    ** rows, then each estimate is computed as:
-    **
-    **        I = (K+D-1)/D
+    ** Use the worst-case estimate: the maximum number of repeated entries
+    ** in the index.
     */
     char *z;
     int i;
@@ -854,8 +859,7 @@ static void statGet(
     sqlite3_snprintf(24, zRet, "%llu", (u64)p->nRow);
     z = zRet + sqlite3Strlen30(zRet);
     for(i=0; i<p->nKeyCol; i++){
-      u64 nDistinct = p->current.anDLt[i] + 1;
-      u64 iVal = (p->nRow + nDistinct - 1) / nDistinct;
+      u64 iVal = p->current.amxEq[i];
       sqlite3_snprintf(24, z, " %llu", iVal);
       z += sqlite3Strlen30(z);
       assert( p->current.anEq[i] );