-
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
planner: improve skyline pruning #26271
Changes from 6 commits
d9d8ce2
b45895a
25b39f5
6ad7d5c
d246484
0685f15
486fdc7
7decc45
b2d975c
116e60b
aadd749
a5ae5a4
cf39a2c
c33aa50
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 |
---|---|---|
|
@@ -254,7 +254,7 @@ func (d *rangeDetacher) detachCNFCondAndBuildRangeForIndex(conditions []expressi | |
) | ||
res := &DetachRangeResult{} | ||
|
||
accessConds, filterConds, newConditions, emptyRange := ExtractEqAndInCondition(d.sctx, conditions, d.cols, d.lengths) | ||
accessConds, filterConds, newConditions, equalCols, emptyRange := ExtractEqAndInCondition(d.sctx, conditions, d.cols, d.lengths) | ||
if emptyRange { | ||
return res, nil | ||
} | ||
|
@@ -286,6 +286,7 @@ func (d *rangeDetacher) detachCNFCondAndBuildRangeForIndex(conditions []expressi | |
res.Ranges = ranges | ||
res.AccessConds = accessConds | ||
res.RemainedConds = filterConds | ||
res.EqualCols = equalCols | ||
if eqOrInCount == len(d.cols) || len(newConditions) == 0 { | ||
res.RemainedConds = append(res.RemainedConds, newConditions...) | ||
return res, nil | ||
|
@@ -465,15 +466,17 @@ func allEqOrIn(expr expression.Expression) bool { | |
// filters: filters is the part that some access conditions need to be evaluate again since it's only the prefix part of char column. | ||
// newConditions: We'll simplify the given conditions if there're multiple in conditions or eq conditions on the same column. | ||
// e.g. if there're a in (1, 2, 3) and a in (2, 3, 4). This two will be combined to a in (2, 3) and pushed to newConditions. | ||
// equalCols: equalCols indicates whether the column is constant under the given conditions for all index columns. | ||
// bool: indicate whether there's nil range when merging eq and in conditions. | ||
func ExtractEqAndInCondition(sctx sessionctx.Context, conditions []expression.Expression, | ||
cols []*expression.Column, lengths []int) ([]expression.Expression, []expression.Expression, []expression.Expression, bool) { | ||
func ExtractEqAndInCondition(sctx sessionctx.Context, conditions []expression.Expression, cols []*expression.Column, | ||
lengths []int) ([]expression.Expression, []expression.Expression, []expression.Expression, []bool, bool) { | ||
var filters []expression.Expression | ||
rb := builder{sc: sctx.GetSessionVars().StmtCtx} | ||
accesses := make([]expression.Expression, len(cols)) | ||
points := make([][]*point, len(cols)) | ||
mergedAccesses := make([]expression.Expression, len(cols)) | ||
newConditions := make([]expression.Expression, 0, len(conditions)) | ||
equalCols := make([]bool, len(cols)) | ||
offsets := make([]int, len(conditions)) | ||
for i, cond := range conditions { | ||
offset := getPotentialEqOrInColOffset(cond, cols) | ||
|
@@ -494,7 +497,7 @@ func ExtractEqAndInCondition(sctx sessionctx.Context, conditions []expression.Ex | |
points[offset] = rb.intersection(points[offset], rb.build(cond)) | ||
// Early termination if false expression found | ||
if len(points[offset]) == 0 { | ||
return nil, nil, nil, true | ||
return nil, nil, nil, nil, true | ||
} | ||
} | ||
for i, ma := range mergedAccesses { | ||
|
@@ -514,7 +517,7 @@ func ExtractEqAndInCondition(sctx sessionctx.Context, conditions []expression.Ex | |
accesses[i] = nil | ||
} else if len(points[i]) == 0 { | ||
// Early termination if false expression found | ||
return nil, nil, nil, true | ||
return nil, nil, nil, nil, true | ||
} else { | ||
// All Intervals are single points | ||
accesses[i] = points2EqOrInCond(sctx, points[i], cols[i]) | ||
|
@@ -527,6 +530,15 @@ func ExtractEqAndInCondition(sctx sessionctx.Context, conditions []expression.Ex | |
newConditions = append(newConditions, conditions[i]) | ||
} | ||
} | ||
for i, cond := range accesses { | ||
if f, ok := cond.(*expression.ScalarFunction); ok && (f.FuncName.L == ast.EQ || f.FuncName.L == ast.NullEQ) { | ||
if _, ok := f.GetArgs()[0].(*expression.Column); ok { | ||
equalCols[i] = true | ||
} else if _, ok := f.GetArgs()[1].(*expression.Column); ok { | ||
equalCols[i] = true | ||
} | ||
} | ||
} | ||
for i, cond := range accesses { | ||
if cond == nil { | ||
accesses = accesses[:i] | ||
|
@@ -546,7 +558,7 @@ func ExtractEqAndInCondition(sctx sessionctx.Context, conditions []expression.Ex | |
} | ||
// We should remove all accessConds, so that they will not be added to filter conditions. | ||
newConditions = removeAccessConditions(newConditions, accesses) | ||
return accesses, filters, newConditions, false | ||
return accesses, filters, newConditions, equalCols, false | ||
} | ||
|
||
// detachDNFCondAndBuildRangeForIndex will detach the index filters from table filters when it's a DNF. | ||
|
@@ -619,6 +631,8 @@ type DetachRangeResult struct { | |
AccessConds []expression.Expression | ||
// RemainedConds is the filter conditions which should be kept after access. | ||
RemainedConds []expression.Expression | ||
// EqualCols indicates whether the column is constant under the given conditions for all index columns. | ||
EqualCols []bool | ||
// EqCondCount is the number of equal conditions extracted. | ||
EqCondCount int | ||
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 var can be deleted now? 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. There is slight difference between how
In the case, 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. I think we can improve it later, not in this PR. What's your opinion? @qw4990 @time-and-fate 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. I think it's OK to improve it later. |
||
// EqOrInCount is the number of equal/in conditions extracted. | ||
|
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 any test case that can cover this rule?
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. https://github.com/xuyifangreeneyes/tidb/blob/116e60b8ad38f7ebfa5ea68b09e87054723a9394/planner/core/logical_plan_test.go#L1703-L1710 In the two cases
f_g
is better thanf
due to this rule.