Skip to content

Commit cd073ea

Browse files
authored
planner: a better way to round scale factor when collecting TopN stats (pingcap#49808) (pingcap#49819)
close pingcap#49801
1 parent 767ec62 commit cd073ea

File tree

3 files changed

+28
-3
lines changed

3 files changed

+28
-3
lines changed

statistics/builder.go

+1-3
Original file line numberDiff line numberDiff line change
@@ -419,10 +419,8 @@ func BuildHistAndTopN(
419419
}
420420
}
421421

422-
for i := 0; i < len(topNList); i++ {
423-
topNList[i].Count *= uint64(sampleFactor)
424-
}
425422
topn := &TopN{TopN: topNList}
423+
topn.Scale(sampleFactor)
426424

427425
if uint64(count) <= topn.TotalCount() || int(hg.NDV) <= len(topn.TopN) {
428426
// TopN includes all sample data

statistics/cmsketch.go

+7
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,13 @@ type TopN struct {
495495
TopN []TopNMeta
496496
}
497497

498+
// Scale scales the TopN by the given factor.
499+
func (c *TopN) Scale(scaleFactor float64) {
500+
for i := range c.TopN {
501+
c.TopN[i].Count = uint64(float64(c.TopN[i].Count) * scaleFactor)
502+
}
503+
}
504+
498505
// AppendTopN appends a topn into the TopN struct.
499506
func (c *TopN) AppendTopN(data []byte, count uint64) {
500507
if c == nil {

statistics/cmsketch_test.go

+20
Original file line numberDiff line numberDiff line change
@@ -390,3 +390,23 @@ func TestMergePartTopN2GlobalTopNWithHists(t *testing.T) {
390390
require.Equal(t, uint64(55), globalTopN.TotalCount(), "should have 55")
391391
require.Len(t, leftTopN, 1, "should have 1 left topN")
392392
}
393+
394+
func TestTopNScale(t *testing.T) {
395+
for _, scaleFactor := range []float64{0.9999, 1.00001, 1.9999, 4.9999, 5.001, 9.99} {
396+
var data []TopNMeta
397+
sumCount := uint64(0)
398+
for i := 0; i < 20; i++ {
399+
cnt := uint64(rand.Intn(100000))
400+
data = append(data, TopNMeta{
401+
Count: cnt,
402+
})
403+
sumCount += cnt
404+
}
405+
topN := TopN{TopN: data}
406+
topN.Scale(scaleFactor)
407+
scaleCount := float64(sumCount) * scaleFactor
408+
delta := math.Abs(float64(topN.TotalCount()) - scaleCount)
409+
roundErrorRatio := delta / scaleCount
410+
require.Less(t, roundErrorRatio, 0.0001)
411+
}
412+
}

0 commit comments

Comments
 (0)