-
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
plan: consider limit during building physcial plan. #1760
Conversation
@@ -25,13 +25,16 @@ func (ts *PhysicalTableScan) matchProperty(prop *requiredProperty, infos ...*phy | |||
rowCount := float64(infos[0].count) | |||
cost := rowCount * netWorkFactor | |||
if len(prop.props) == 0 { | |||
return &physicalPlanInfo{p: ts, cost: cost, count: infos[0].count} | |||
return enforceProperty(prop, &physicalPlanInfo{p: ts, cost: cost, count: infos[0].count}) |
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.
if len(prop.props) == 0 && prop.limit != 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.
It's no need to check whether prop.limit is nil. If it is, it won't change the plan info.
@@ -76,6 +76,8 @@ type Selection struct { | |||
// but after we converted to CNF(Conjunctive normal form), it can be | |||
// split into a list of AND conditions. | |||
Conditions []expression.Expression | |||
|
|||
aboveTableScan bool |
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 about this property.
@@ -75,7 +78,7 @@ func (is *PhysicalIndexScan) matchProperty(prop *requiredProperty, infos ...*phy | |||
cost *= 2 | |||
} | |||
if len(prop.props) == 0 { | |||
return &physicalPlanInfo{p: is, cost: cost, count: infos[0].count} | |||
return enforceProperty(&requiredProperty{limit: prop.limit}, &physicalPlanInfo{p: is, cost: cost, count: infos[0].count}) |
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.
Define a limitProperty
, it will be used in several places.
return info | ||
} | ||
|
||
func removeLimit(prop *requiredProperty, removeAll bool) *requiredProperty { |
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 about when and why we need to remove limit, and when removeAll need to be false when removeAll need to be true.
sortKeyLen: prop.sortKeyLen, | ||
limit: prop.limit} | ||
if len(prop.props) > 0 { | ||
} |
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.
Unfinished or useless?
ead75fe
to
b2526e9
Compare
// removeLimit removes limit from prop. For example, When handling Sort,Limit -> Selection, we can't pass the Limit | ||
// across the selection, because selection decreases the size of data, but we can pass the Sort below the selection. In | ||
// this case, we set removeAll true. When handling Limit(1,1) -> LeftOuterJoin, we can pass the limit across join's left | ||
// path, because the left outer join increases the size of data, but we can't pass offset value. So we set remove All to false. |
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.
So when removeAll
is set to false, it's meant to remove offset, then how about define a different function named removeOffset
?
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.
Current designment is orthogonal
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 don't get your point.
It's confusing that removeLimit
is not doing what it's supposed to do.
When removeAll
is set to false, it doesn't remove limit at all.
@@ -77,6 +77,7 @@ type Selection struct { | |||
// split into a list of AND conditions. | |||
Conditions []expression.Expression | |||
|
|||
// aboveTableScan means if this selection's child is a table scan or index scan. |
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.
So aboveTableScan
is false if the selection's child is a join or having? Then above
is not accurate, and TableScan
doesn't contains IndexScan
.
How about onTable
?
} | ||
} | ||
err := types.SortDatums(datums) | ||
if err != nil { | ||
return nil, errors.Trace(err) | ||
log.Error(err.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.
We will loss the 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.
I think this error shouldn't make sql fail. Instead, it can forbid this condition to push down.
} | ||
val, err := codec.EncodeValue(nil, datums...) | ||
if err != nil { | ||
return nil, errors.Trace(err) | ||
log.Error(err.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.
ditto
@@ -325,6 +323,58 @@ func addPlanToResponse(p PhysicalPlan, planInfo *physicalPlanInfo) *physicalPlan | |||
return &physicalPlanInfo{p: np, cost: planInfo.cost, count: planInfo.count} | |||
} | |||
|
|||
func enforceProperty(prop *requiredProperty, info *physicalPlanInfo) *physicalPlanInfo { |
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.
// removeLimit removes limit from prop. For example, When handling Sort,Limit -> Selection, we can't pass the Limit | ||
// across the selection, because selection decreases the size of data, but we can pass the Sort below the selection. In | ||
// this case, we set removeAll true. When handling Limit(1,1) -> LeftOuterJoin, we can pass the limit across join's left | ||
// path, because the left outer join increases the size of data, but we can't pass offset value. So we set remove All to false. |
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.
remove All -> removeAll
@@ -677,33 +735,72 @@ func (p *Union) convert2PhysicalPlan(prop *requiredProperty) (*physicalPlanInfo, | |||
childInfos = append(childInfos, info) | |||
} | |||
info = p.matchProperty(prop, childInfos...) | |||
info = enforceProperty(limitProperty(limit), info) |
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.
When should we call this function?
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 should call this function upon every operator that refuses the required property.
info, err := p.getPlanInfo(prop) | ||
if err != nil { | ||
return nil, errors.Trace(err) | ||
} | ||
if info != nil { | ||
return info, nil | ||
} | ||
info, err = p.GetChildByIndex(0).(LogicalPlan).convert2PhysicalPlan(prop) | ||
// Firstly, we try to push order |
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.
Is there a secondly?
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 add a "secondly" comment.
} | ||
} | ||
|
||
func (p *physicalTableSource) addTopN(prop *requiredProperty) { |
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 support top-n on localstore?
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 havn't. I will implement it in next pr.
09fcec8
to
611e890
Compare
611e890
to
80977e9
Compare
PTAL @coocood |
LGTM |
@@ -325,6 +323,62 @@ func addPlanToResponse(p PhysicalPlan, planInfo *physicalPlanInfo) *physicalPlan | |||
return &physicalPlanInfo{p: np, cost: planInfo.cost, count: planInfo.count} | |||
} | |||
|
|||
// enforceProperty add an topN or sort upon current operator. |
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 thie function add limit upon current operator?
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, you are right. I will update the comment
} | ||
|
||
id := column.ID | ||
// Zero Column ID is not a column from table, can not support for now. | ||
if id == 0 { | ||
return nil, nil | ||
return 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.
if id == 0 || id == -1 { return nil}
@shenli PTAL |
LGTM |
The purpose of this pr is to push down topn operator.#1746 I change the plan part before supporting it in local store.
@shenli @coocood @zimulala @tiancaiamao @XuHuaiyu PTAL