-
Notifications
You must be signed in to change notification settings - Fork 5.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
*: update stats using query feedback #6197
Conversation
/run-all-tests |
domain/domain.go
Outdated
continue | ||
} | ||
err = statsHandle.HandleUpdateStats() | ||
if err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a metrics here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is better to add metrics in a separate pr, it is already too large now.
} | ||
case <-dumpFeedbackTicker.C: | ||
err = statsHandle.DumpStatsFeedbackToKV() | ||
if err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will do it in a separate pr.
statistics/cmsketch.go
Outdated
@@ -54,6 +54,17 @@ func (c *CMSketch) InsertBytes(bytes []byte) { | |||
} | |||
} | |||
|
|||
func (c *CMSketch) setValue(h1, h2 uint64, count uint32) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add comment for this function.
return buf.Bytes(), nil | ||
} | ||
|
||
func decodeFeedback(val []byte, q *QueryFeedback, c *CMSketch) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add comments for the following code logic.
} | ||
|
||
for _, t := range tests { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add comment for the test case.
@@ -190,6 +191,100 @@ func (h *Handle) dumpTableStatDeltaToKV(id int64, delta variable.TableDelta) (bo | |||
return updated, errors.Trace(err) | |||
} | |||
|
|||
// DumpStatsFeedbackToKV dumps the stats feedback to KV. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to add a few metrics for the following operations?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I will do it in a separate pr.
statistics/handle.go
Outdated
// For now, we do not use the query feedback, so just set it to 1. | ||
const maxQueryFeedBackCount = 1 | ||
// MaxQueryFeedbackCount is the max number of feedback that cache in memory. | ||
var MaxQueryFeedbackCount = 1000 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how about 1 << 10 ?
statistics/update.go
Outdated
if err != nil { | ||
return errors.Trace(err) | ||
} | ||
sql := fmt.Sprintf("delete from mysql.stats_feedback where table_id = %d and hist_id = %d and is_index = %d", tableID, hist.ID, isIndex) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
May the delete exceeds transaction limit?
statistics/feedback.go
Outdated
@@ -493,3 +493,127 @@ func buildNewHistogram(h *Histogram, buckets []bucket) *Histogram { | |||
} | |||
return hist | |||
} | |||
|
|||
// QueryFeedbackPB is used to serialize the QueryFeedback. | |||
type QueryFeedbackPB struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The name has PB
but It's not protobuf
.
Do you plan to change it to protobuf
in the future?
@@ -243,7 +243,7 @@ func (s *testSuite) TestAggregation(c *C) { | |||
|
|||
result = tk.MustQuery("select count(*) from information_schema.columns") | |||
// When adding new memory columns in information_schema, please update this variable. | |||
columnCountOfAllInformationSchemaTables := "737" | |||
columnCountOfAllInformationSchemaTables := "741" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
5 column added instead of 4?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is 4 column added.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, i misread it.
LGTM |
@@ -54,6 +54,18 @@ func (c *CMSketch) InsertBytes(bytes []byte) { | |||
} | |||
} | |||
|
|||
// setValue sets the count for value that hashed into (h1, h2). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(h1, h2) is an interval?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it means the hash value pair.
PTAL @winoros |
statistics/feedback.go
Outdated
func encodeFeedback(q *QueryFeedback) ([]byte, error) { | ||
var pb *queryFeedback | ||
var err error | ||
if q.hist.tp.Tp == mysql.TypeLong { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we make sure that the Tp there is only TypeLong
? Not possible to be TypeLongLong
?
statistics/update.go
Outdated
|
||
// HandleUpdateStats update the stats using feedback. | ||
func (h *Handle) HandleUpdateStats(is infoschema.InfoSchema) error { | ||
sql := fmt.Sprintf("select table_id, hist_id, is_index, feedback from mysql.stats_feedback order by table_id, hist_id, is_index") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need to fmt.Sprintf
statistics/update.go
Outdated
} | ||
sql := fmt.Sprintf("insert into mysql.stats_feedback (table_id, hist_id, is_index, feedback) values "+ | ||
"(%d, %d, %d, X'%X')", fb.tableID, fb.hist.ID, isIndex, vals) | ||
_, err = h.ctx.(sqlexec.SQLExecutor).Execute(context.TODO(), sql) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not using RestrictedSQLExecutor
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
PTAL @winoros |
This pr dumps the collected feedback into kv and use these feedback to update the stats, including the histogram and CM Sketch.
PTAL @coocood @winoros @shenli