-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Stop copying LogicalPlan and Exprs in PushDownFilter
(4%-6% faster planning)
#10444
Conversation
4c204e6
to
a618a2e
Compare
PushDownFilter
PushDownFilter
(4%-6% faster planning)
a618a2e
to
79cafcb
Compare
79cafcb
to
891d415
Compare
join_plan: &LogicalPlan, | ||
left: &LogicalPlan, | ||
right: &LogicalPlan, | ||
inferred_join_predicates: Vec<Expr>, |
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 is refactored so that the Join is passed in, rather than a LogicalPlan
and the embedded Join
Plan as well as a reference to the embedded pieces
}; | ||
// Are there any new join predicates that can be inferred from the filter expressions? | ||
let inferred_join_predicates = | ||
infer_join_predicates(&join, &predicates, &on_filters)?; |
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.
pulled out to a function to make it easier to see what is going on -- the logic was not changed
}; | ||
|
||
let child_plan = filter.input.as_ref(); |
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.
Here is the core change -- instead of looking at the input by ref
the PR now takes its ownership and then updates the accounting to avoid clone
ing
}, | ||
LogicalPlan::CrossJoin(_) => Ok((true, true)), | ||
_ => internal_err!("lr_is_preserved only valid for JOIN nodes"), | ||
fn lr_is_preserved(join_type: JoinType) -> Result<(bool, 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.
the plan was always a join so rather than having to re-check the plan, I changed to simply take the JoinType
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.
👍
predicates: &[Expr], | ||
on_filters: &[Expr], | ||
) -> Result<Vec<Expr>> { | ||
if join.join_type != JoinType::Inner { |
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 logic was refactored from above
@jackwener I know this is a fairly large PR, but I think you were the one who did the last major rework of this code. Do you happen to have any time to review this 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.
A very nice job to me! Thank you @alamb .
Besides enhancing performance, I am pleased to see that the readability of this part of the code has significantly improved. During the PR review process, I found the entire workflow to be much clearer.
}, | ||
LogicalPlan::CrossJoin(_) => Ok((true, true)), | ||
_ => internal_err!("lr_is_preserved only valid for JOIN nodes"), | ||
fn lr_is_preserved(join_type: JoinType) -> Result<(bool, 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.
👍
fn insert_below( | ||
plan: LogicalPlan, | ||
new_child: LogicalPlan, | ||
) -> Result<Transformed<LogicalPlan>> { |
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 a great common method to me👍
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 I should pull it into optimizer/utils 🤔
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.
Thank you very much for the review @jackwener 🙏
fn insert_below( | ||
plan: LogicalPlan, | ||
new_child: LogicalPlan, | ||
) -> Result<Transformed<LogicalPlan>> { |
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 I should pull it into optimizer/utils 🤔
Draft as it depends onPushDownFilter
rule #10437Expr::try_as_col
, deprecateExpr::try_into_col
(speed up optimizer) #10448Which issue does this PR close?
Closes #10291
Rationale for this change
Follow on to #10366 from @dmitrybugakov ❤️
Make planning faster by removing clones in filter pushdown
What changes are included in this PR?
Rewrite the
PushDownFilter
to not copy thingsAre these changes tested?
Functionally it is covered by existing tests (specifically there are unit tests in the module, the sqllogictest and tpcds planner tests)
Are there any user-facing changes?
There is no functional change
Performance improvement shows 4-6% faster for TPCH/TPDS planning
Details