]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Simplifications to PRAGMA optimize to make it easier to use. It always
authordrh <>
Mon, 19 Feb 2024 13:50:09 +0000 (13:50 +0000)
committerdrh <>
Mon, 19 Feb 2024 13:50:09 +0000 (13:50 +0000)
tries to ANALYZE unanalyzed indexes.  The 0x10000 flag just makes it check
for size changes in all tables.

FossilOrigin-Name: 44ed7f4cd07a88a2fdd303a2c78e6babe01d7344b399bd2b80ed68d75a77aaa2

manifest
manifest.uuid
src/pragma.c

index 54ba56837e05813595ca7fe682d51f36178d345f..fdb16737f154dad3f393f1e1bc20c3e75637a712 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Change\sthe\s0x20000\sbit\s(use\sanalysis\slimit)\sto\s0x10,\smeaning\sthat\sthis\sfeature\nis\son\sby\sdefault.\s\sThe\sdefault\sanalysis\slimit\sis\schanged\sto\s2000\swhich\sis\nalmost\salways\ssufficient\sfor\saccurate\sanalysis\sresults.
-D 2024-02-19T13:06:27.586
+C Simplifications\sto\sPRAGMA\soptimize\sto\smake\sit\seasier\sto\suse.\s\sIt\salways\ntries\sto\sANALYZE\sunanalyzed\sindexes.\s\sThe\s0x10000\sflag\sjust\smakes\sit\scheck\nfor\ssize\schanges\sin\sall\stables.
+D 2024-02-19T13:50:09.987
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -732,7 +732,7 @@ F src/parse.y bfd6da46fc895cd8237400ff485d04ab0b32e47eb56de20982bb7f53e56c1f42
 F src/pcache.c 040b165f30622a21b7a9a77c6f2e4877a32fb7f22d4c7f0d2a6fa6833a156a75
 F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5
 F src/pcache1.c 602acb23c471bb8d557a6f0083cc2be641d6cafcafa19e481eba7ef4c9ca0f00
-F src/pragma.c b877efa88ea41560ee5dd95daa30c8cadb743381c59b8921a5143bf0792c6e3b
+F src/pragma.c 9197331dd283a6010bb4e2c129a9015f854203d27fa6fbe89e1aea742b78351c
 F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7
 F src/prepare.c 371f6115cb69286ebc12c6f2d7511279c2e47d9f54f475d46a554d687a3b312c
 F src/printf.c 18fbdf028345c8fbe6044f5f5bfda5a10d48d6287afef088cc21b0ca57985640
@@ -2162,8 +2162,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P d13b79eae6df7f9d1f3b8062ddc75a12ff038196b3d752d2672a9925fa45ca56
-R e258fa6228ef566d2b5670b2822a20d1
+P 4abd47b5917099a2f74e53e12c987da0722304a5e9a93b6d43015c1f45c48444
+R 39db09ba2f5384fee677814cc2cbe4fe
 U drh
-Z e864b92d6fb5e0c6f09ca55fa83dd960
+Z cf23276671f3baaf4e4f3579488af586
 # Remove this line to create a well-formed Fossil manifest.
index 9cda73c43e934161ac4b643080466e7db235f4dc..f1cc73e3f05307327dd33a011ff681c9daf34553 100644 (file)
@@ -1 +1 @@
-4abd47b5917099a2f74e53e12c987da0722304a5e9a93b6d43015c1f45c48444
\ No newline at end of file
+44ed7f4cd07a88a2fdd303a2c78e6babe01d7344b399bd2b80ed68d75a77aaa2
\ No newline at end of file
index 6e1fc8bc002054922931041d702322ac48a388d4..53dc9ced30485cf548d43e84a302df1859f0ced4 100644 (file)
@@ -2425,11 +2425,15 @@ void sqlite3Pragma(
   **               currently (2024-02-19) set to 2000, which is such that
   **               the worst case run-time for PRAGMA optimize on a 100MB
   **               database will usually be less than 100 milliseconds on
-  **               a RaspberryPI-4 class machine.  Off by default.
+  **               a RaspberryPI-4 class machine.  On by default.
+  **
+  **    0x00020    Run ANALYZE on any table that has a complete index
+  **               (an index without a WHERE clause) that lacks an entry
+  **               in the sqlite_stat1 table.  On by default.
   **
   **    0x10000    Look at tables to see if they need to be reanalyzed
-  **               even if they have not been queried during the current
-  **               connection.  Off by default.
+  **               due to growth or shrinkage even if they have not been
+  **               queried during the current connection.  Off by default.
   **
   ** The default MASK is and always shall be 0x0fffe.  In the current
   ** implementation, the default mask only covers the 0x00002 optimization,
@@ -2444,18 +2448,25 @@ void sqlite3Pragma(
   **
   ** (1) MASK bit 0x00002 is set.
   **
-  ** (2) Either the 0x10000 MASK bit is set or else the query planner used
-  **     sqlite_stat1-style statistics for one or more indexes of the table
-  **     at some point during the lifetime of the current connection.
+  ** (2) The table is an ordinary table, not a virtual table or view.
   **
-  ** (3) One or more indexes of the table are currently unanalyzed OR
-  **     the number of rows in the table has increased or decreased by
-  **     10-fold (the new size is either greater than 10 times the old
-  **     size or less than 1/10th of the old size).
+  ** (3) The table name does not begin with "sqlite_".
   **
-  ** (4) The table is an ordinary table, not a virtual table or view.
+  ** (4) One or more of the following is true:
+  **      (4a) The 0x10000 MASK bit is set.
+  **      (4b) One or more complete indexes on the table lacks an entry
+  **           in the sqlite_stat1 table.
+  **      (4c) The query planner used sqlite_stat1-style statistics for one
+  **           or more indexes of the tableat some point during the lifetime
+  **           of the current connection.
   **
-  ** (5) The table name does not begin with "sqlite_".
+  ** (5) One or more of the following is true:
+  **      (5a) One or mroe complete indexes on the table lacks an entry
+  **           in the sqlite_stat1 table.  (Same as 4a)
+  **      (5b) The number of rows in the table has increased or decreased by
+  **           10-fold.  In other words, the current size of the table is
+  **           10 times larger than the size in sqlite_stat1 or else the
+  **           current size is less than 1/10th the size in sqlite_stat1.
   **
   ** The rules for when tables are analyzed are likely to change in
   ** future releases.  Future versions of SQLite might accept a string
@@ -2473,7 +2484,7 @@ void sqlite3Pragma(
     char *zSubSql;         /* SQL statement for the OP_SqlExec opcode */
     u32 opMask;            /* Mask of operations to perform */
     int nLimit;            /* Analysis limit to use */
-    int once = 0;          /* One-time initialization done */
+    int nCheck = 0;        /* Number of tables to be optimized */
 
     if( zRight ){
       opMask = (u32)sqlite3Atoi(zRight);
@@ -2503,30 +2514,42 @@ void sqlite3Pragma(
         /* Do not scan system tables */
         if( 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) ) continue;
 
+        /* Find the size of the table as last recorded in sqlite_stat1.
+        ** If any complete index (index without a WHERE clause) is unanalyzed,
+        ** then the threshold is -1 to indicate a new, unanalyzed index
+        */
+        szThreshold = pTab->nRowLogEst;
+        for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+          if( !pIdx->hasStat1 && pIdx->pPartIdxWhere==0 ){
+            szThreshold = -1; /* Always analyze if any index lacks statistics */
+            break;
+          }
+        }
+
         /* If table pTab has not been used in a way that would benefit from
         ** having analysis statistics during the current session, then skip it,
         ** unless the 0x10000 MASK bit is set. */
-        if( (pTab->tabFlags & TF_MaybeReanalyze)==0
-         && (opMask & 0x10000)==0
-        ){
+        if( (pTab->tabFlags & TF_MaybeReanalyze)!=0 ){
+          /* Check for size change if stat1 has been used for a query */
+        }else if( opMask & 0x10000 ){
+          /* Check for size change if 0x10000 is set */
+        }else if( pTab->pIndex!=0 && szThreshold<0 ){
+          /* Do analysis if unanalyzed complete indexes exists */
+        }else{
+          /* Otherwise, we can skip this table */
           continue;
         }
 
-        /* Hold a write transaction open for efficiency */
-        if( !once || 1 ){
+        nCheck++;
+        if( nCheck==2 ){
+          /* If ANALYZE might be invoked two or more times, hold a write
+          ** transaction for efficiency */
           sqlite3BeginWriteOperation(pParse, 0, iDb);
-          once = 1;
         }
 
         /* Reanalyze if the table is 10 times larger or smaller than
-        ** the last analysis */
-        szThreshold = pTab->nRowLogEst;
-        for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
-          if( !pIdx->hasStat1 ){
-            szThreshold = -1; /* Always analyze if any index lacks statistics */
-            break;
-          }
-        }
+        ** the last analysis.  Unconditional reanalysis if there are
+        ** unanalyzed complete indexes. */
         if( szThreshold>=0 ){
           LogEst iRange = 33;   /* 10x size change */
           sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead);