Skip to content

statistics: split OutOfRangeRowCount into count-independent shape and scaling - #70178

Open
terry1purcell wants to merge 3 commits into
pingcap:masterfrom
terry1purcell:oorshape
Open

statistics: split OutOfRangeRowCount into count-independent shape and scaling#70178
terry1purcell wants to merge 3 commits into
pingcap:masterfrom
terry1purcell:oorshape

Conversation

@terry1purcell

@terry1purcell terry1purcell commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: ref #67097

Problem Summary:

Histogram.OutOfRangeRowCount mixes two concerns in one function: the geometry of the out-of-range estimate (derived only from the histogram and the queried range) and the scaling of that geometry by realtimeRowCount/modifyCount. Because the function returns a row count already scaled to the realtime counts, any caller that wants to memoize out-of-range estimation must key its cache by realtimeCount and modifyCount as well (see the column estimate cache discussion in #67098). Coincidentally-equal counts would then risk incorrect cache reuse.

What changed and how does it work?

Pure refactor of Histogram.OutOfRangeRowCount in pkg/statistics/histogram.go, with no behavior change:

  • OutOfRangeShape (new struct + method) computes the count-independent geometry: the oneValue floor (NotNullCount/histNDV), the histogram NDV floored at 1, empty-histogram and impossible-range flags, and the triangular-distribution overlap percentages of the queried range with the out-of-range regions.
  • ScaleOutOfRangeShape (new method) applies the current realtimeRowCount and modifyCount to a shape: the OptObjectiveDeterminate early return, the low-NDV oneValue adjustment, added-rows scaling, the risk range skew ratio, and the final min/est/max derivation.
  • OutOfRangeRowCount keeps its exact signature and is now the composition of the two, so all call sites (column and index estimation paths) and all estimates are unchanged.

With this split, a follow-up can compute the shape once per (histogram, range) and rescale it as counts vary, which is the prerequisite for removing realtimeCount/modifyCount from the column estimate cache key introduced in #67098.

Check List

Tests

  • Unit test
  • Integration test
  • Manual test (add detailed scripts or steps below)
  • No need to test
    • I checked and no code files have been changed.

Covered by the existing out-of-range estimation suites, run with failpoints enabled:

go test ./pkg/statistics/ -tags=intest,deadlock -count=1
go test ./pkg/planner/cardinality/ -tags=intest,deadlock -count=1

Side effects

  • Performance regression: Consumes more CPU
  • Performance regression: Consumes more Memory
  • Breaking backward compatibility

Documentation

  • Affects user behaviors
  • Contains syntax changes
  • Contains variable changes
  • Contains experimental features
  • Changes MySQL compatibility

Release note

Please refer to Release Notes Language Style Guide to write a quality release note.

None

🤖 Generated with Claude Code

https://claude.ai/code/session_01SyrcMzpvGA1rafdRP4m6HU

Summary by CodeRabbit

  • Refactor
    • Improved out-of-range row estimation by splitting range/shape analysis from realtime/modify count scaling.
    • Added a reusable estimation “shape” so empty, impossible, and zero/invalid-width range cases are handled consistently.
    • Kept prior estimation behavior while making the logic easier to apply across query planning scenarios.

… scaling

Refactor Histogram.OutOfRangeRowCount into two parts:

- OutOfRangeShape computes the count-independent geometry of the
  out-of-range estimate (oneValue floor, histogram NDV, and the
  triangular-distribution overlap percentages), depending only on the
  histogram and the queried range.
- ScaleOutOfRangeShape applies realtimeRowCount and modifyCount to a
  shape (determinate-mode handling, low-NDV oneValue adjustment,
  added-rows scaling, skew ratio, and min/max derivation).

OutOfRangeRowCount keeps its signature as the composition of the two,
so all call sites and estimates are unchanged. This separation allows a
caller to compute and reuse the shape across changes in the realtime
counts, a prerequisite for removing realtimeCount/modifyCount from the
column estimate cache key introduced in pingcap#67098.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SyrcMzpvGA1rafdRP4m6HU
@ti-chi-bot ti-chi-bot Bot added release-note-none Denotes a PR that doesn't merit a release note. component/statistics size/L Denotes a PR that changes 100-499 lines, ignoring generated files. sig/planner SIG: Planner labels Jul 28, 2026
@ti-chi-bot

ti-chi-bot Bot commented Jul 28, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign henrybw for approval. For more information see the Code Review Process.
Please ensure that each of them provides their approval before proceeding.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: bfecbf81-7406-4283-92af-8041028ff031

📥 Commits

Reviewing files that changed from the base of the PR and between ac637e2 and 126594f.

📒 Files selected for processing (1)
  • pkg/statistics/histogram.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/statistics/histogram.go

📝 Walkthrough

Walkthrough

Histogram.OutOfRangeRowCount now separates predicate geometry from row-count scaling through the exported OutOfRangeShape type and associated methods, including explicit handling for empty, impossible, zero-width, and unsigned-clamped ranges.

Changes

Out-of-range estimation

Layer / File(s) Summary
Shape contract and geometry computation
pkg/statistics/histogram.go
Adds OutOfRangeShape and computes histogram NDV, one-value floors, predicate widths, impossible cases, and overlap percentages.
Shape scaling and row estimate integration
pkg/statistics/histogram.go
OutOfRangeRowCount delegates to shape computation, while ScaleOutOfRangeShape applies realtime, modification-count, and maximum-case scaling.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Poem

I’m a rabbit with a histogram chart,
Splitting shape from counts with care.
Widths may vanish, bounds may hop,
Scaling follows every overlap.
Squeak—clean estimates everywhere!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the refactor to split out-of-range estimation into shape computation and scaling.
Description check ✅ Passed The description includes the issue link, problem summary, implementation details, tests, and release-note placeholder, so it is mostly complete.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Jul 28, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 65.85366% with 14 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.0028%. Comparing base (874bb79) to head (ffd3275).

Additional details and impacted files
@@               Coverage Diff                @@
##             master     #70178        +/-   ##
================================================
- Coverage   76.3238%   74.0028%   -2.3211%     
================================================
  Files          2041       2070        +29     
  Lines        559479     583664     +24185     
================================================
+ Hits         427016     431928      +4912     
- Misses       131563     150743     +19180     
- Partials        900        993        +93     
Flag Coverage Δ
integration 41.8551% <65.8536%> (+2.1972%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
dumpling 59.8807% <ø> (ø)
parser ∅ <ø> (∅)
br 46.6707% <ø> (-16.0218%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors out-of-range row-count estimation in pkg/statistics by separating the count-independent “shape” computation from the scaling step that applies realtimeRowCount / modifyCount, enabling callers to cache the geometry across changing realtime counts without changing estimation behavior.

Changes:

  • Introduced OutOfRangeShape to capture the count-independent geometry of out-of-range estimation.
  • Refactored Histogram.OutOfRangeRowCount into OutOfRangeShape(...) + ScaleOutOfRangeShape(...) while keeping the original signature and behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pkg/statistics/histogram.go
@terry1purcell

Copy link
Copy Markdown
Contributor Author

/retest-required

1 similar comment
@terry1purcell

Copy link
Copy Markdown
Contributor Author

/retest-required

@ti-chi-bot

ti-chi-bot Bot commented Jul 29, 2026

Copy link
Copy Markdown

@terry1purcell: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
idc-jenkins-ci-tidb/check_dev_2 126594f link true /test check-dev2

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component/statistics release-note-none Denotes a PR that doesn't merit a release note. sig/planner SIG: Planner size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants