GetColumnRowCount estimates the row count by a slice of Range.
(sctx planctx.PlanContext, c *statistics.Column, ranges []*ranger.Range, realtimeRowCount, modifyCount int64, pkIsHandle bool)
| 182 | |
| 183 | // GetColumnRowCount estimates the row count by a slice of Range. |
| 184 | func GetColumnRowCount(sctx planctx.PlanContext, c *statistics.Column, ranges []*ranger.Range, realtimeRowCount, modifyCount int64, pkIsHandle bool) (float64, error) { |
| 185 | sc := sctx.GetSessionVars().StmtCtx |
| 186 | debugTrace := sc.EnableOptimizerDebugTrace |
| 187 | if debugTrace { |
| 188 | debugtrace.EnterContextCommon(sctx) |
| 189 | defer debugtrace.LeaveContextCommon(sctx) |
| 190 | } |
| 191 | var rowCount float64 |
| 192 | for _, rg := range ranges { |
| 193 | highVal := *rg.HighVal[0].Clone() |
| 194 | lowVal := *rg.LowVal[0].Clone() |
| 195 | if highVal.Kind() == types.KindString { |
| 196 | highVal.SetBytes(collate.GetCollator(highVal.Collation()).Key(highVal.GetString())) |
| 197 | } |
| 198 | if lowVal.Kind() == types.KindString { |
| 199 | lowVal.SetBytes(collate.GetCollator(lowVal.Collation()).Key(lowVal.GetString())) |
| 200 | } |
| 201 | cmp, err := lowVal.Compare(sc.TypeCtx(), &highVal, collate.GetBinaryCollator()) |
| 202 | if err != nil { |
| 203 | return 0, errors.Trace(err) |
| 204 | } |
| 205 | lowEncoded, err := codec.EncodeKey(sc.TimeZone(), nil, lowVal) |
| 206 | err = sc.HandleError(err) |
| 207 | if err != nil { |
| 208 | return 0, err |
| 209 | } |
| 210 | highEncoded, err := codec.EncodeKey(sc.TimeZone(), nil, highVal) |
| 211 | err = sc.HandleError(err) |
| 212 | if err != nil { |
| 213 | return 0, err |
| 214 | } |
| 215 | if debugTrace { |
| 216 | debugTraceStartEstimateRange(sctx, rg, lowEncoded, highEncoded, rowCount) |
| 217 | } |
| 218 | if cmp == 0 { |
| 219 | // case 1: it's a point |
| 220 | if !rg.LowExclude && !rg.HighExclude { |
| 221 | // In this case, the row count is at most 1. |
| 222 | if pkIsHandle { |
| 223 | rowCount++ |
| 224 | if debugTrace { |
| 225 | debugTraceEndEstimateRange(sctx, 1, debugTraceUniquePoint) |
| 226 | } |
| 227 | continue |
| 228 | } |
| 229 | var cnt float64 |
| 230 | cnt, err = equalRowCountOnColumn(sctx, c, lowVal, lowEncoded, realtimeRowCount, modifyCount) |
| 231 | if err != nil { |
| 232 | return 0, errors.Trace(err) |
| 233 | } |
| 234 | // If the current table row count has changed, we should scale the row count accordingly. |
| 235 | cnt *= c.GetIncreaseFactor(realtimeRowCount) |
| 236 | rowCount += cnt |
| 237 | if debugTrace { |
| 238 | debugTraceEndEstimateRange(sctx, cnt, debugTracePoint) |
| 239 | } |
| 240 | } |
| 241 | continue |