]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Change the way samples for the sqlite_stat4 table are collected.
authordan <dan@noemail.net>
Wed, 7 Aug 2013 16:15:32 +0000 (16:15 +0000)
committerdan <dan@noemail.net>
Wed, 7 Aug 2013 16:15:32 +0000 (16:15 +0000)
FossilOrigin-Name: 13ed5ac13562e7a39905d70fd47059f4d8001bba

manifest
manifest.uuid
src/analyze.c

index bce64529b7bf8dedf7314d06f6c3aa337ca11094..ac641a833e185c0520ef2695005ec84541008826 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sthe\s".dump"\scommand\son\sthe\scommand-line\sshell\sso\sthat\sit\sworks\sfor\n"sqlite_stat4"\sin\saddition\sto\s"sqlite_stat1".
-D 2013-08-07T16:04:27.058
+C Change\sthe\sway\ssamples\sfor\sthe\ssqlite_stat4\stable\sare\scollected.
+D 2013-08-07T16:15:32.765
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -157,7 +157,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
 F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
 F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad
 F src/alter.c 2af0330bb1b601af7a7789bf7229675fd772a083
-F src/analyze.c b8b0d15347ae34772f0df9b6d02848dea9dfe8a3
+F src/analyze.c 8dfc6a70274314bcb0ba41d218e840a5591dd895
 F src/attach.c 1816f5a9eea8d2010fc2b22b44f0f63eb3a62704
 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
 F src/backup.c 43b348822db3e4cef48b2ae5a445fbeb6c73a165
@@ -1106,7 +1106,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae
 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
-P 9159b43eb2cb5d6ed18a5ad168fa27134fec2553
-R f3f1a72dd300dcd2969e458028afbec5
-U drh
-Z 194a793cc38dc0b3add1e00828469db6
+P 1e80c4b12dbb5beab422e2a33a8782ac9d767321
+R 872f61a83df4a029ddba5de7545c74a2
+U dan
+Z ad2d3dd84452de28ba71d37d31a2a3f2
index 1c323591dfd7eaf3b18b4eb8d0cfc4c6deff6eee..503648f1195b34cb203bd7524075921e78f3adda 100644 (file)
@@ -1 +1 @@
-1e80c4b12dbb5beab422e2a33a8782ac9d767321
\ No newline at end of file
+13ed5ac13562e7a39905d70fd47059f4d8001bba
\ No newline at end of file
index 17cecb43d93bf5c7e5ee35d1d6259b702bdefaf5..49a34a04b756173e18aff1d584454f1e45495405 100644 (file)
@@ -218,14 +218,13 @@ typedef struct Stat4Accum Stat4Accum;
 struct Stat4Accum {
   tRowcnt nRow;             /* Number of rows in the entire table */
   tRowcnt nPSample;         /* How often to do a periodic sample */
-  int iMin;                 /* Index of entry with minimum nSumEq and hash */
+  int iMin;                 /* Index of entry with minimum nEq and hash */
   int mxSample;             /* Maximum number of samples to accumulate */
   int nSample;              /* Current number of samples */
   int nCol;                 /* Number of columns in the index */
   u32 iPrn;                 /* Pseudo-random number used for sampling */
   struct Stat4Sample {
     i64 iRowid;                /* Rowid in main table of the key */
-    tRowcnt nSumEq;            /* Sum of anEq[] values */
     tRowcnt *anEq;             /* sqlite_stat4.nEq */
     tRowcnt *anLt;             /* sqlite_stat4.nLt */
     tRowcnt *anDLt;            /* sqlite_stat4.nDLt */
@@ -349,23 +348,38 @@ static void stat4Push(
   assert( p->nCol>0 );
   assert( argc==(2 + 3*p->nCol) );
 
-  /* Set nSumEq to the sum of all nEq parameters. */
-  for(i=0; i<p->nCol; i++){
-    nSumEq += sqlite3_value_int64(aEq[i]);
-  }
-  if( nSumEq==0 ) return;
-
-  /* Figure out if this sample will be used. Set isPSample to true if this
-  ** is a periodic sample, or false if it is being captured because of a
-  ** large nSumEq value. If the sample will not be used, return early.  */
+  /* Figure out if this sample will be used. There are two reasons a
+  ** sample may be used:
+  **
+  **   1. It may be a periodic sample. In this case set isPSample to true
+  **      as well. Or,
+  **
+  **   2. Less than p->mxSample samples have been collected so far, or
+  **
+  **   3. It is more desirable than some other non-periodic sample that has
+  **      already been collected. Samples are compared based on the values
+  **      in the anEq array, starting from last (right-most index column)
+  **      to first (left-most index column). If all elements of the anEq
+  **      array are equal, samples are compared by hash value.
+  */
   h = p->iPrn = p->iPrn*1103515245 + 12345;
   if( (nLt/p->nPSample)!=((nEq+nLt)/p->nPSample) ){
     doInsert = isPSample = 1;
-  }else if( (p->nSample<p->mxSample)
-         || (nSumEq>p->a[iMin].nSumEq)
-         || (nSumEq==p->a[iMin].nSumEq && h>p->a[iMin].iHash) 
-  ){
+  }else if( p->nSample<p->mxSample ){
     doInsert = 1;
+  }else{
+    tRowcnt *aMinEq = p->a[iMin].anEq;
+    for(i=p->nCol-1; i>=0; i--){
+      i64 nEq = sqlite3_value_int64(aEq[i]);
+      if( nEq<aMinEq[i] ) break;
+      if( nEq>aMinEq[i] ){
+        doInsert = 1;
+        break;
+      }
+    }
+    if( i<0 && h>p->a[iMin].iHash ){
+      doInsert = 1;
+    }
   }
   if( !doInsert ) return;
 
@@ -387,7 +401,6 @@ static void stat4Push(
   pSample->iRowid = rowid;
   pSample->iHash = h;
   pSample->isPSample = isPSample;
-  pSample->nSumEq = nSumEq;
   for(i=0; i<p->nCol; i++){
     pSample->anEq[i] = sqlite3_value_int64(aEq[i]);
     pSample->anLt[i] = sqlite3_value_int64(aLt[i]);
@@ -397,18 +410,21 @@ static void stat4Push(
 
   /* Find the new minimum */
   if( p->nSample==p->mxSample ){
-    u32 iHash = 0;                /* Hash corresponding to iMin/nSumEq entry */
-    i64 nMinEq = LARGEST_INT64;   /* Smallest nSumEq seen so far */
-    assert( iMin = -1 );
-
+    iMin = -1;
     for(i=0; i<p->mxSample; i++){
       if( p->a[i].isPSample ) continue;
-      if( (p->a[i].nSumEq<nMinEq)
-       || (p->a[i].nSumEq==nMinEq && p->a[i].iHash<iHash)
-      ){
+      if( iMin<0 ){
         iMin = i;
-        nMinEq = p->a[i].nSumEq;
-        iHash = p->a[i].iHash;
+      }else{
+        int j;
+        for(j=p->nCol-1; j>=0; j++){
+          i64 iCmp = (p->a[iMin].anEq[j] - p->a[i].anEq[j]);
+          if( iCmp<0 ){ iMin = i; }
+          if( iCmp ) break;
+        }
+        if( j==0 && p->a[iMin].iHash<p->a[i].iHash ){
+          iMin = i;
+        }
       }
     }
     assert( iMin>=0 );