-
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: optimize (left outer) (anti) semi join which has no other condition #47764
Changes from 5 commits
cadadf4
cde8044
00f2010
2ec7b2f
f8ab5f6
09fa6e3
9e27d1e
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 |
---|---|---|
|
@@ -106,6 +106,11 @@ type joiner interface { | |
// parameter passed to `onMissMatch`. | ||
onMissMatch(hasNull bool, outer chunk.Row, chk *chunk.Chunk) | ||
|
||
// isSemiJoinWithoutCondition returns if it's a semi join and has no condition. | ||
// If true, at most one matched row is needed to match inners, which can optimize a lot when | ||
// there are a lot of matched rows. | ||
isSemiJoinWithoutCondition() bool | ||
|
||
// Clone deep copies a joiner. | ||
Clone() joiner | ||
} | ||
|
@@ -426,6 +431,10 @@ func (j *semiJoiner) tryToMatchOuters(outers chunk.Iterator, inner chunk.Row, ch | |
|
||
func (*semiJoiner) onMissMatch(bool, chunk.Row, *chunk.Chunk) {} | ||
|
||
func (j *semiJoiner) isSemiJoinWithoutCondition() bool { | ||
return len(j.conditions) == 0 | ||
} | ||
|
||
// Clone implements joiner interface. | ||
func (j *semiJoiner) Clone() joiner { | ||
return &semiJoiner{baseJoiner: j.baseJoiner.Clone()} | ||
|
@@ -490,6 +499,10 @@ func (naaj *nullAwareAntiSemiJoiner) onMissMatch(_ bool, outer chunk.Row, chk *c | |
chk.AppendRowByColIdxs(outer, naaj.lUsed) | ||
} | ||
|
||
func (naaj *nullAwareAntiSemiJoiner) isSemiJoinWithoutCondition() bool { | ||
return len(naaj.conditions) == 0 | ||
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. Is this optimazation works for nullaware join? And since only 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. No. This function is useless for null-aware semi join. |
||
} | ||
|
||
func (naaj *nullAwareAntiSemiJoiner) Clone() joiner { | ||
return &nullAwareAntiSemiJoiner{baseJoiner: naaj.baseJoiner.Clone()} | ||
} | ||
|
@@ -559,6 +572,10 @@ func (j *antiSemiJoiner) onMissMatch(hasNull bool, outer chunk.Row, chk *chunk.C | |
} | ||
} | ||
|
||
func (j *antiSemiJoiner) isSemiJoinWithoutCondition() bool { | ||
return len(j.conditions) == 0 | ||
} | ||
|
||
func (j *antiSemiJoiner) Clone() joiner { | ||
return &antiSemiJoiner{baseJoiner: j.baseJoiner.Clone()} | ||
} | ||
|
@@ -641,6 +658,10 @@ func (j *leftOuterSemiJoiner) onMissMatch(hasNull bool, outer chunk.Row, chk *ch | |
} | ||
} | ||
|
||
func (j *leftOuterSemiJoiner) isSemiJoinWithoutCondition() bool { | ||
return len(j.conditions) == 0 | ||
} | ||
|
||
func (j *leftOuterSemiJoiner) Clone() joiner { | ||
return &leftOuterSemiJoiner{baseJoiner: j.baseJoiner.Clone()} | ||
} | ||
|
@@ -713,8 +734,12 @@ func (*nullAwareAntiLeftOuterSemiJoiner) tryToMatchOuters(chunk.Iterator, chunk. | |
return nil, err | ||
} | ||
|
||
func (naal *nullAwareAntiLeftOuterSemiJoiner) isSemiJoinWithoutCondition() bool { | ||
return len(naal.conditions) == 0 | ||
} | ||
|
||
func (naal *nullAwareAntiLeftOuterSemiJoiner) Clone() joiner { | ||
return &antiLeftOuterSemiJoiner{baseJoiner: naal.baseJoiner.Clone()} | ||
return &nullAwareAntiLeftOuterSemiJoiner{baseJoiner: naal.baseJoiner.Clone()} | ||
} | ||
|
||
type antiLeftOuterSemiJoiner struct { | ||
|
@@ -798,6 +823,10 @@ func (j *antiLeftOuterSemiJoiner) onMissMatch(hasNull bool, outer chunk.Row, chk | |
} | ||
} | ||
|
||
func (j *antiLeftOuterSemiJoiner) isSemiJoinWithoutCondition() bool { | ||
return len(j.conditions) == 0 | ||
} | ||
|
||
func (j *antiLeftOuterSemiJoiner) Clone() joiner { | ||
return &antiLeftOuterSemiJoiner{baseJoiner: j.baseJoiner.Clone()} | ||
} | ||
|
@@ -877,6 +906,10 @@ func (j *leftOuterJoiner) onMissMatch(_ bool, outer chunk.Row, chk *chunk.Chunk) | |
chk.AppendPartialRowByColIdxs(lWide, j.defaultInner, j.rUsed) | ||
} | ||
|
||
func (*leftOuterJoiner) isSemiJoinWithoutCondition() bool { | ||
return false | ||
} | ||
|
||
func (j *leftOuterJoiner) Clone() joiner { | ||
return &leftOuterJoiner{baseJoiner: j.baseJoiner.Clone()} | ||
} | ||
|
@@ -952,6 +985,10 @@ func (j *rightOuterJoiner) onMissMatch(_ bool, outer chunk.Row, chk *chunk.Chunk | |
chk.AppendPartialRowByColIdxs(lWide, outer, j.rUsed) | ||
} | ||
|
||
func (*rightOuterJoiner) isSemiJoinWithoutCondition() bool { | ||
return false | ||
} | ||
|
||
func (j *rightOuterJoiner) Clone() joiner { | ||
return &rightOuterJoiner{baseJoiner: j.baseJoiner.Clone()} | ||
} | ||
|
@@ -1035,6 +1072,10 @@ func (j *innerJoiner) tryToMatchOuters(outers chunk.Iterator, inner chunk.Row, c | |
|
||
func (*innerJoiner) onMissMatch(bool, chunk.Row, *chunk.Chunk) {} | ||
|
||
func (*innerJoiner) isSemiJoinWithoutCondition() bool { | ||
return false | ||
} | ||
|
||
func (j *innerJoiner) Clone() joiner { | ||
return &innerJoiner{baseJoiner: j.baseJoiner.Clone()} | ||
} |
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.
Will it be better to add a comment example here for how to iterator the stored ptrs?
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.
Added. Nice suggestion.