@@ -937,7 +937,7 @@ func (hg *Histogram) OutOfRange(val types.Datum) bool {
937
937
func (hg * Histogram ) OutOfRangeRowCount (
938
938
sctx context.PlanContext ,
939
939
lDatum , rDatum * types.Datum ,
940
- modifyCount , histNDV int64 ,
940
+ modifyCount , histNDV int64 , increaseFactor float64 ,
941
941
) (result float64 ) {
942
942
debugTrace := sctx .GetSessionVars ().StmtCtx .EnableOptimizerDebugTrace
943
943
if debugTrace {
@@ -1052,38 +1052,35 @@ func (hg *Histogram) OutOfRangeRowCount(
1052
1052
rightPercent = (math .Pow (boundR - actualL , 2 ) - math .Pow (boundR - actualR , 2 )) / math .Pow (histWidth , 2 )
1053
1053
}
1054
1054
1055
- totalPercent := leftPercent * 0.5 + rightPercent * 0.5
1056
- if totalPercent > 1 {
1057
- totalPercent = 1
1058
- }
1055
+ totalPercent := min (leftPercent * 0.5 + rightPercent * 0.5 , 1.0 )
1059
1056
rowCount = totalPercent * hg .NotNullCount ()
1060
1057
1061
- // Upper bound logic
1058
+ // Upper & lower bound logic.
1059
+ upperBound := rowCount
1060
+ if histNDV > 0 {
1061
+ upperBound = hg .NotNullCount () / float64 (histNDV )
1062
+ }
1062
1063
1063
1064
allowUseModifyCount := sctx .GetSessionVars ().GetOptObjective () != variable .OptObjectiveDeterminate
1064
- // Use the modifyCount as the upper bound. Note that modifyCount contains insert, delete and update. So this is
1065
- // a rather loose upper bound.
1066
- // There are some scenarios where we need to handle out-of-range estimation after both insert and delete happen.
1067
- // But we don't know how many increases are in the modifyCount. So we have to use this loose bound to ensure it
1068
- // can produce a reasonable results in this scenario.
1069
- if rowCount > float64 (modifyCount ) && allowUseModifyCount {
1070
- return float64 (modifyCount )
1071
- }
1072
-
1073
- // In OptObjectiveDeterminate mode, we can't rely on the modify count anymore.
1074
- // An upper bound is necessary to make the estimation make sense for predicates with bound on only one end, like a > 1.
1075
- // But it's impossible to have a reliable upper bound in all cases.
1076
- // We use 1/NDV here (only the Histogram part is considered) and it seems reasonable and good enough for now.
1065
+
1077
1066
if ! allowUseModifyCount {
1078
- var upperBound float64
1079
- if histNDV > 0 {
1080
- upperBound = hg .NotNullCount () / float64 (histNDV )
1081
- }
1082
- if rowCount > upperBound {
1083
- return upperBound
1084
- }
1067
+ // In OptObjectiveDeterminate mode, we can't rely on the modify count anymore.
1068
+ // An upper bound is necessary to make the estimation make sense for predicates with bound on only one end, like a > 1.
1069
+ // We use 1/NDV here (only the Histogram part is considered) and it seems reasonable and good enough for now.
1070
+ return min (rowCount , upperBound )
1071
+ }
1072
+
1073
+ // If the modifyCount is large (compared to original table rows), then any out of range estimate is unreliable.
1074
+ // Assume at least 1/NDV is returned
1075
+ if float64 (modifyCount ) > hg .NotNullCount () && rowCount < upperBound {
1076
+ rowCount = upperBound
1077
+ } else if rowCount < upperBound {
1078
+ // Adjust by increaseFactor if our estimate is low
1079
+ rowCount *= increaseFactor
1085
1080
}
1086
- return rowCount
1081
+
1082
+ // Use modifyCount as a final bound
1083
+ return min (rowCount , float64 (modifyCount ))
1087
1084
}
1088
1085
1089
1086
// Copy deep copies the histogram.
0 commit comments