-
Notifications
You must be signed in to change notification settings - Fork 6.1k
planner: add HasTiflash to avoid generating unnecessary mpp task | tidb-test=pr/2660 #65250
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
base: master
Are you sure you want to change the base?
Changes from all commits
4dc3406
90742e1
683b0bd
19d9bc4
15c4031
d03199c
e9e92f8
98c4041
0696a7f
6b07c49
c21759e
06392b9
5c56b7c
ec9c6d6
e690597
440463b
c4a667d
1d3987e
26f1641
f96c861
e934c20
7375a50
1031bc9
d397b62
5e998ba
220fb7d
db1350b
a3a70b4
e808ce7
35cc4a5
e8e2ca2
2626068
c586f6d
1029aef
43cf58c
a2d1dce
6b8cc93
d506236
8a11ed7
c2c5188
cbebb20
c4f9a5d
7b77e97
e2e7e83
724cc85
09d2839
d56d5f1
9e6f59b
4556b11
558156f
5c640c8
469ae5a
e41ba99
cd9bfc2
7c125c4
1056dda
bb586ab
ad5961f
18ce622
a71fcac
4c1805d
6eb15f5
08ea8c0
ea04afd
e36f8f0
7e17bde
1652cff
0add956
415ac9b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -246,7 +246,7 @@ func (opt *Optimizer) onPhaseImplementation(_ base.PlanContext, g *memo.Group) ( | |
| prop := &property.PhysicalProperty{ | ||
| ExpectedCnt: math.MaxFloat64, | ||
| } | ||
| preparePossibleProperties(g, make(map[*memo.Group][][]*expression.Column)) | ||
| preparePossibleProperties(g, make(map[*memo.Group]*base.PossiblePropertiesInfo)) | ||
| // TODO replace MaxFloat64 costLimit by variable from sctx, or other sources. | ||
| impl, err := opt.implGroup(g, prop, math.MaxFloat64) | ||
| if err != nil { | ||
|
|
@@ -355,18 +355,28 @@ func (opt *Optimizer) implGroupExpr(cur *memo.GroupExpr, reqPhysProp *property.P | |
| // preparePossibleProperties recursively calls LogicalPlan PreparePossibleProperties | ||
| // interface. It will fulfill the the possible properties fields of LogicalAggregation | ||
| // and LogicalJoin. | ||
| func preparePossibleProperties(g *memo.Group, propertyMap map[*memo.Group][][]*expression.Column) [][]*expression.Column { | ||
| func preparePossibleProperties(g *memo.Group, propertyMap map[*memo.Group]*base.PossiblePropertiesInfo) *base.PossiblePropertiesInfo { | ||
| if prop, ok := propertyMap[g]; ok { | ||
| return prop | ||
| } | ||
| groupPropertyMap := make(map[string][]*expression.Column) | ||
| groupHasTiflash := false | ||
| for elem := g.Equivalents.Front(); elem != nil; elem = elem.Next() { | ||
| expr := elem.Value.(*memo.GroupExpr) | ||
| childrenProperties := make([][][]*expression.Column, len(expr.Children)) | ||
| childrenProperties := make([]*base.PossiblePropertiesInfo, len(expr.Children)) | ||
| for i, child := range expr.Children { | ||
| childrenProperties[i] = preparePossibleProperties(child, propertyMap) | ||
| childProps := preparePossibleProperties(child, propertyMap) | ||
| if childProps == nil { | ||
| childProps = &base.PossiblePropertiesInfo{} | ||
| } | ||
| childrenProperties[i] = childProps | ||
| } | ||
| exprInfo := expr.ExprNode.PreparePossibleProperties(expr.Schema(), childrenProperties...) | ||
| if exprInfo == nil { | ||
| continue | ||
| } | ||
| exprProperties := expr.ExprNode.PreparePossibleProperties(expr.Schema(), childrenProperties...) | ||
| groupHasTiflash = groupHasTiflash || exprInfo.HasTiflash | ||
| exprProperties := exprInfo.Orders | ||
| for _, newPropCols := range exprProperties { | ||
| // Check if the prop has already been in `groupPropertyMap`. | ||
| newProp := property.PhysicalProperty{SortItems: property.SortItemsFromCols(newPropCols, true)} | ||
|
|
@@ -380,6 +390,10 @@ func preparePossibleProperties(g *memo.Group, propertyMap map[*memo.Group][][]*e | |
| for _, prop := range groupPropertyMap { | ||
| resultProps = append(resultProps, prop) | ||
| } | ||
| propertyMap[g] = resultProps | ||
| return resultProps | ||
| result := &base.PossiblePropertiesInfo{ | ||
| Orders: resultProps, | ||
| HasTiflash: groupHasTiflash, | ||
| } | ||
|
Comment on lines
+393
to
+396
|
||
| propertyMap[g] = result | ||
| return result | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -224,7 +224,7 @@ type LogicalPlan interface { | |
|
|
||
| // PreparePossibleProperties is only used for join and aggregation. Like group by a,b,c, all permutation of (a,b,c) is | ||
| // valid, but the ordered indices in leaf plan is limited. So we can get all possible order properties by a pre-walking. | ||
| PreparePossibleProperties(schema *expression.Schema, childrenProperties ...[][]*expression.Column) [][]*expression.Column | ||
| PreparePossibleProperties(schema *expression.Schema, childrenProperties ...*PossiblePropertiesInfo) *PossiblePropertiesInfo | ||
|
|
||
| // ExtractCorrelatedCols extracts correlated columns inside the LogicalPlan. | ||
| ExtractCorrelatedCols() []*expression.CorrelatedColumn | ||
|
|
@@ -378,3 +378,63 @@ type PhysicalJoin interface { | |
| GetInnerChildIdx() int | ||
| GetJoinType() JoinType | ||
| } | ||
|
|
||
| // PossiblePropertiesInfo is used to store all possible order properties. | ||
| type PossiblePropertiesInfo struct { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is interesting |
||
| // all possible order properties | ||
| Orders [][]*expression.Column | ||
| // HasTiflash is a runtime pruning signal and is intentionally excluded from hash/equals. | ||
| HasTiflash bool | ||
| } | ||
|
|
||
| // Hash64 implements the HashEquals interface. | ||
| func (info *PossiblePropertiesInfo) Hash64(h base.Hasher) { | ||
| if info == nil { | ||
| h.HashByte(base.NilFlag) | ||
| return | ||
| } | ||
| h.HashByte(base.NotNilFlag) | ||
| if info.Orders == nil { | ||
| h.HashByte(base.NilFlag) | ||
| } else { | ||
| h.HashByte(base.NotNilFlag) | ||
| h.HashInt(len(info.Orders)) | ||
| for _, one := range info.Orders { | ||
| h.HashInt(len(one)) | ||
| for _, col := range one { | ||
| col.Hash64(h) | ||
| } | ||
|
Comment on lines
+402
to
+406
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
💡 Proposed fix for _, one := range info.Orders {
h.HashInt(len(one))
for _, col := range one {
- col.Hash64(h)
+ if col == nil {
+ h.HashByte(base.NilFlag)
+ continue
+ }
+ h.HashByte(base.NotNilFlag)
+ col.Hash64(h)
}
}
}🤖 Prompt for AI Agents |
||
| } | ||
| } | ||
| } | ||
|
|
||
| // Equals implements the HashEquals interface. | ||
| func (info *PossiblePropertiesInfo) Equals(other any) bool { | ||
| info2, ok := other.(*PossiblePropertiesInfo) | ||
| if !ok { | ||
| return false | ||
| } | ||
| if info == nil { | ||
| return info2 == nil | ||
| } | ||
| if info2 == nil { | ||
| return false | ||
| } | ||
| if (info.Orders == nil && info2.Orders != nil) || (info.Orders != nil && info2.Orders == nil) || len(info.Orders) != len(info2.Orders) { | ||
| return false | ||
| } | ||
| for i, one := range info.Orders { | ||
| if len(one) != len(info2.Orders[i]) { | ||
| return false | ||
| } | ||
| for j, col := range one { | ||
| if (col == nil && info2.Orders[i][j] != nil) || (col != nil && info2.Orders[i][j] == nil) { | ||
| return false | ||
| } | ||
| if col != nil && !col.Equals(info2.Orders[i][j]) { | ||
| return false | ||
| } | ||
| } | ||
| } | ||
| return true | ||
| } | ||
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.
childPropertiesis constructed with onlyOrderand leavesHasTiflashat the zero value (false). AnyPreparePossiblePropertiesimplementation that depends onHasTiflash(many in this PR) will then computehasTiflash=falsefor parent nodes under cascades, potentially disabling MPP/TiFlash plan generation even when TiFlash replicas exist.Consider propagating
HasTiflashthrough cascades logical properties (e.g., extend the group logical property to carry it) and populate it here; otherwisePreparePossibleProperties(...).HasTiflashwill not be meaningful in cascades mode.