From: drh <> Date: Wed, 27 Apr 2022 16:41:56 +0000 (+0000) Subject: When computing STAT1 values using ANALYZE, if a ratio comes out to be between X-Git-Tag: version-3.39.0~190 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=609959285bc035aa18da0d89bea484e1b5432105;p=thirdparty%2Fsqlite.git When computing STAT1 values using ANALYZE, if a ratio comes out to be between 1.0 and 1.1, then round it down to 1 rather than the using the default rounding rule of changing it to 2. The reduces the estimation error for the case where a column value is very nearly, but not quite unique. FossilOrigin-Name: eb59c46a5aed69bc6fd096997bf24c082e533c1085439f6ec1fbe5ff78e8b374 --- diff --git a/manifest b/manifest index 5d25cfd023..dcee977a82 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stest\sproblem\sin\srbubusy.test\scausing\sa\scrash\sunder\ssome\scircumstances. -D 2022-04-27T13:33:48.684 +C When\scomputing\sSTAT1\svalues\susing\sANALYZE,\sif\sa\sratio\scomes\sout\sto\sbe\sbetween\n1.0\sand\s1.1,\sthen\sround\sit\sdown\sto\s1\srather\sthan\sthe\susing\sthe\sdefault\srounding\nrule\sof\schanging\sit\sto\s2.\s\sThe\sreduces\sthe\sestimation\serror\sfor\sthe\ncase\swhere\sa\scolumn\svalue\sis\svery\snearly,\sbut\snot\squite\sunique. +D 2022-04-27T16:41:56.099 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -487,7 +487,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 9395ece9850ad57c6fbb453aeb5185be4bae3b159c4b37611425c565124ee849 -F src/analyze.c 3a119baeb03053c154029877454d41bb8fd79d4d1eb583392f2289b3554a75bc +F src/analyze.c aabdf3769c7fd9954a8ec508eb7041ae174b66f88d12c47199fabbea9a646467 F src/attach.c 4431f82f0247bf3aaf91589acafdff77d1882235c95407b36da1585c765fbbc8 F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf F src/backup.c a2891172438e385fdbe97c11c9745676bec54f518d4447090af97189fd8e52d7 @@ -1951,8 +1951,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 b1bec72043f798f4d4d30e6b60a45ed4dc521115c8a9f97bb8228e3f089deefb -R f8e9d661e065b7babfd72a5655e4ad71 -U dan -Z 3cd41b751eccac6d73d356239c542a95 +P bc5bbd9fa636cc9ef0cbbc0600b8fc1404b9732670ac4e7a8b5a230fbce758d5 +R 5515b70c241c679d58c02a7cda432aa8 +U drh +Z e146713923a218edc001415f7d000194 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9b2e970b93..0444092686 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bc5bbd9fa636cc9ef0cbbc0600b8fc1404b9732670ac4e7a8b5a230fbce758d5 \ No newline at end of file +eb59c46a5aed69bc6fd096997bf24c082e533c1085439f6ec1fbe5ff78e8b374 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index e8699653f7..39009899ab 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -847,9 +847,14 @@ static void statGet( ** * "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: + ** rows, then each estimate is usually computed as: ** ** I = (K+D-1)/D + ** + ** In other words, I is K/D rounded up to the next whole integer. + ** However, if I is between 1.0 and 1.1 (in other words if I is + ** close to 1.0 but just a little larger) then do not round up but + ** instead keep the I value at 1.0. */ sqlite3_str sStat; /* Text of the constructed "stat" line */ int i; /* Loop counter */ @@ -860,6 +865,7 @@ static void statGet( for(i=0; inKeyCol; i++){ u64 nDistinct = p->current.anDLt[i] + 1; u64 iVal = (p->nRow + nDistinct - 1) / nDistinct; + if( iVal==2 && p->nRow*10 <= nDistinct*11 ) iVal = 1; sqlite3_str_appendf(&sStat, " %llu", iVal); assert( p->current.anEq[i] ); }