-
Notifications
You must be signed in to change notification settings - Fork 5.8k
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
executor: remove *MVMap from agg executor #7541
Conversation
executor/aggfuncs/sets.go
Outdated
@@ -19,7 +19,7 @@ import ( | |||
|
|||
type decimalSet map[types.MyDecimal]struct{} | |||
type float64Set map[float64]struct{} | |||
type stringSet map[string]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.
Move this file to util
package?
executor/aggregate.go
Outdated
"github.com/spaolacci/murmur3" | ||
"golang.org/x/net/context" | ||
"sort" |
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.
Move this to the first block.
Any benchmark result? |
executor/aggregate.go
Outdated
for _, item := range w.groupByItems { | ||
v, err := item.Eval(row) | ||
v, isNull, err := item.EvalString(ctx, row) |
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.
we can not simply call EvalString
here.
executor/aggregate.go
Outdated
var err error | ||
w.groupKey, err = codec.EncodeValue(sc, w.groupKey[:0], w.groupValDatums...) | ||
return w.groupKey, errors.Trace(err) | ||
return groupKey, 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.
can we reuse a []byte
to reduce the string object allocation?
executor/aggregate.go
Outdated
} | ||
partialResults := e.getPartialResults(groupKey) | ||
|
||
sort.Strings(e.sortedGroupKey) |
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 this sort is needed?
executor/aggregate.go
Outdated
if item.GetType().Tp == mysql.TypeNewDecimal { | ||
v.SetLength(0) | ||
} | ||
v, isNull, err := item.EvalString(ctx, row) |
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.
Maybe it's not safe to call EvalString
?
Some bugs remained, working on this |
/run-all-tests |
/run-all-tests |
/run-common-test tidb-test=pr/614 |
@XuHuaiyu Please post the benchmark result here. |
The |
Optimize points:
The performance is not improved obviously because that the access to StringSet which is used to replace MVMap seems cost as much as the access to MVMap.
After using a string slice to store the group keys and traverse it instead of the MVMap when fetching the final result, we got about 33.47% CPU performance improvement.
Optimize points:
|
Seen from the profile picture, it seems the GC overhead is not much more than the master branch. @coocood |
@@ -680,35 +675,34 @@ func (e *HashAggExec) execute(ctx context.Context) (err error) { | |||
} | |||
} | |||
|
|||
func (e *HashAggExec) getGroupKey(row chunk.Row) ([]byte, error) { | |||
vals := make([]types.Datum, 0, len(e.GroupByItems)) | |||
func (e *HashAggExec) getGroupKey(row chunk.Row) (string, 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.
This function can be further optimized. Maybe in the next PR.
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.
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.
we can change the way to calculate the []byte
according to the group by
items.
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.
this method maybe better return []byte
directly and make to string lazy happen, and then modify StringSet
add a Exists
override method that accept []byte
as argument, then use this small trick golang/go@8072f46#diff-590553aade2ea7ef319660a8151c5eb9R581
I feel @coocood want to make StringSet
be map[[n]byte]struct
if we have some "magic design" make groupKey be fixed length? 🐱
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.
maybe hack.String
or hack.Slice
is what you want.
@XuHuaiyu |
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
/run-all-tests |
/run-common-test tidb-test=pr/614 |
1 similar comment
/run-common-test tidb-test=pr/614 |
/run-common-test tidb-test=pr/614 |
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
What problem does this PR solve?
Fix #7450
What is changed and how it works?
Change groupMap of HashAggExec and HashAggFinalWorker from
*MVMap
tostringSet
, thus we can avoid some cost ofruntime.sliceToString
,runtime.byteSliceToString
, and the access to MVMap.Check List
Tests
Exist tests
Code changes
Side effects
Related changes