Skip to content
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: add hash join v2 #53208

Merged
merged 177 commits into from
Jun 14, 2024

Conversation

windtalker
Copy link
Contributor

What problem does this PR solve?

Issue Number: ref #53127

Problem Summary:

What changed and how does it work?

Design doc: #53196
Currently, only inner join and left outer join is supported.

Check List

Tests

  • Unit test
  • Integration test
  • Manual test (add detailed scripts or steps below)
  • No need to test
    • I checked and no code files have been changed.

Side effects

  • Performance regression: Consumes more CPU
  • Performance regression: Consumes more Memory
  • Breaking backward compatibility

Documentation

  • Affects user behaviors
  • Contains syntax changes
  • Contains variable changes
  • Contains experimental features
  • Changes MySQL compatibility

Release note

Please refer to Release Notes Language Style Guide to write a quality release note.

None

@ti-chi-bot ti-chi-bot bot added do-not-merge/invalid-title release-note-none size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. sig/planner SIG: Planner labels May 13, 2024
Copy link

tiprow bot commented May 13, 2024

Hi @windtalker. Thanks for your PR.

PRs from untrusted users cannot be marked as trusted with /ok-to-test in this repo meaning untrusted PR authors can never trigger tests themselves. Collaborators can still trigger tests on the PR using /test all.

I understand the commands that are listed here.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@windtalker windtalker changed the title Hash join v2 unsafe pointer executor: add hash join v2 May 13, 2024
@windtalker windtalker mentioned this pull request May 13, 2024
13 tasks
// See the License for the specific language governing permissions and
// limitations under the License.

package join
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing? Can we remove it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will add a basic test

Copy link

codecov bot commented May 13, 2024

Codecov Report

Attention: Patch coverage is 85.88193% with 397 lines in your changes missing coverage. Please review.

Project coverage is 56.3978%. Comparing base (b4563c0) to head (c58b20a).
Report is 1 commits behind head on master.

Additional details and impacted files
@@                Coverage Diff                @@
##             master     #53208         +/-   ##
=================================================
- Coverage   72.4538%   56.3978%   -16.0561%     
=================================================
  Files          1508       1632        +124     
  Lines        432016     598190     +166174     
=================================================
+ Hits         313012     337366      +24354     
- Misses        99547     237685     +138138     
- Partials      19457      23139       +3682     
Flag Coverage Δ
integration 37.0129% <9.0682%> (?)
tiprow_ft ?
unit 71.5067% <85.8819%> (+0.0763%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
dumpling 52.9656% <ø> (+0.1133%) ⬆️
parser ∅ <ø> (∅)
br 50.5103% <ø> (+8.2882%) ⬆️

@windtalker windtalker added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label May 13, 2024
@hawkingrei
Copy link
Member

/ok-to-test

BuildWorkers: make([]*join.BuildWorkerV2, v.Concurrency),
HashJoinCtxV2: &join.HashJoinCtxV2{
OtherCondition: v.OtherConditions,
PartitionNumber: mathutil.Min(int(v.Concurrency), 16),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
PartitionNumber: mathutil.Min(int(v.Concurrency), 16),
PartitionNumber: min(int(v.Concurrency), 16),

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@windtalker windtalker force-pushed the hash_join_v2_unsafe_pointer branch from 811ae7b to b8de444 Compare May 15, 2024 02:21
@windtalker windtalker changed the title executor: add hash join v2 executor: add hash join v2 | tidb-test=pr/2332 May 15, 2024
@ti-chi-bot ti-chi-bot bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label May 15, 2024
@windtalker windtalker force-pushed the hash_join_v2_unsafe_pointer branch from 668ff10 to 6f78742 Compare May 16, 2024 01:47
@windtalker
Copy link
Contributor Author

/test check-dev2

Copy link

tiprow bot commented May 16, 2024

@windtalker: The specified target(s) for /test were not found.
The following commands are available to trigger required jobs:

  • /test fast_test_tiprow
  • /test tidb_parser_test

Use /test all to run all jobs.

In response to this:

/test check-dev2

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@windtalker windtalker force-pushed the hash_join_v2_unsafe_pointer branch 2 times, most recently from 43644ee to 150fdb7 Compare May 17, 2024 06:41
@windtalker
Copy link
Contributor Author

/test unit-test

Copy link

tiprow bot commented May 17, 2024

@windtalker: The specified target(s) for /test were not found.
The following commands are available to trigger required jobs:

  • /test fast_test_tiprow
  • /test tidb_parser_test

Use /test all to run all jobs.

In response to this:

/test unit-test

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@windtalker windtalker force-pushed the hash_join_v2_unsafe_pointer branch from 4403be5 to 3d78136 Compare May 20, 2024 07:07
@windtalker windtalker changed the title executor: add hash join v2 | tidb-test=pr/2332 executor: add hash join v2 May 22, 2024
@windtalker windtalker force-pushed the hash_join_v2_unsafe_pointer branch from 3d78136 to 61cc71c Compare May 22, 2024 05:41
// step 1. fetch data from build side child and build a hash table;
// step 2. fetch data from probe child in a background goroutine and probe the hash table in multiple join workers.
func (e *HashJoinV2Exec) Next(ctx context.Context, req *chunk.Chunk) (err error) {
if !e.prepared {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use atomic type for e.prepared? As Close may be called at the same time.

@windtalker windtalker force-pushed the hash_join_v2_unsafe_pointer branch from 61cc71c to 9aa750d Compare May 24, 2024 10:08
return err
}

// 2. build rowtable
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we need to add // 1. in previous code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines 561 to 575
h := fnv.New64()
fakePartIndex := 0
for logicalRowIndex, physicalRowIndex := range b.usedRows {
if (b.filterVector != nil && !b.filterVector[physicalRowIndex]) || (b.nullKeyVector != nil && b.nullKeyVector[physicalRowIndex]) {
b.hashValue[logicalRowIndex] = uint64(fakePartIndex)
b.partIdxVector[logicalRowIndex] = fakePartIndex
fakePartIndex = (fakePartIndex + 1) % hashJoinCtx.PartitionNumber
continue
}
h.Write(b.serializedKeyVectorBuffer[logicalRowIndex])
hash := h.Sum64()
b.hashValue[logicalRowIndex] = hash
b.partIdxVector[logicalRowIndex] = int(hash % uint64(hashJoinCtx.PartitionNumber))
h.Reset()
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can put these codes into a single function? As the purpose of them is clear and the reader could catch the point of them with function name.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

|---------------------|-----------------|----------------------|-------------------------------|
| | | |
V V V V
next_row_ptr null_map serialized_key/key_length row_data
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can add each field's byte number in the introduction?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems meaningless since only next_row_ptr is 8 bytes, and all the other field is variable length.

Comment on lines 34 to 38
const sizeOfNextPtr = int(unsafe.Sizeof(unsafe.Pointer(nil)))
const sizeOfLengthField = int(unsafe.Sizeof(uint64(1)))
const sizeOfUInt64 = int(unsafe.Sizeof(uint64(1)))
const sizeOfInt = int(unsafe.Sizeof(int(1)))
const sizeOfFloat64 = int(unsafe.Sizeof(float64(1)))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of them have been defined in tidb/pkg/util/serialization/common_util.go

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good suggestion, update the code.

}

func (b *rowTableBuilder) appendToRowTable(chk *chunk.Chunk, hashJoinCtx *HashJoinCtxV2, workerID int) error {
fakeAddrByte := make([]byte, 8)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can set it as a global variable or variable in rowTableBuilder, so that we can avoid unnecessary duplicate allocation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines 676 to 690
// next_row_ptr
seg.rawData = append(seg.rawData, fakeAddrByte...)
rowLength += 8
// null_map
if nullMapLength := rowTableMeta.nullMapLength; nullMapLength > 0 {
bitmap := make([]byte, nullMapLength)
for colIndexInRowTable, colIndexInRow := range rowTableMeta.rowColumnsOrder {
colIndexInBitMap := colIndexInRowTable + rowTableMeta.colOffsetInNullMap
if row.IsNull(colIndexInRow) {
bitmap[colIndexInBitMap/8] |= 1 << (7 - colIndexInBitMap%8)
}
}
seg.rawData = append(seg.rawData, bitmap...)
rowLength += nullMapLength
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment with // next_row_ptr and // null_map makes reader confused. I think it's better to create function like serializeNextRowPtr. Similarly, serializing null_map and serialized_key/key_length can also be encapsulated into a function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Signed-off-by: xufei <xufeixw@mail.ustc.edu.cn>
Signed-off-by: xufei <xufeixw@mail.ustc.edu.cn>
Signed-off-by: xufei <xufeixw@mail.ustc.edu.cn>
Signed-off-by: xufei <xufeixw@mail.ustc.edu.cn>
Signed-off-by: xufei <xufeixw@mail.ustc.edu.cn>
Signed-off-by: xufei <xufeixw@mail.ustc.edu.cn>
Signed-off-by: xufei <xufeixw@mail.ustc.edu.cn>
Signed-off-by: xufei <xufeixw@mail.ustc.edu.cn>
Signed-off-by: xufei <xufeixw@mail.ustc.edu.cn>
Signed-off-by: xufei <xufeixw@mail.ustc.edu.cn>
Signed-off-by: xufei <xufeixw@mail.ustc.edu.cn>
Signed-off-by: xufei <xufeixw@mail.ustc.edu.cn>
Signed-off-by: xufei <xufeixw@mail.ustc.edu.cn>
Signed-off-by: xufei <xufeixw@mail.ustc.edu.cn>
Signed-off-by: xufei <xufeixw@mail.ustc.edu.cn>
Signed-off-by: xufei <xufeixw@mail.ustc.edu.cn>
Signed-off-by: xufei <xufeixw@mail.ustc.edu.cn>
Signed-off-by: xufei <xufeixw@mail.ustc.edu.cn>
Signed-off-by: xufei <xufeixw@mail.ustc.edu.cn>
Signed-off-by: xufei <xufeixw@mail.ustc.edu.cn>
Signed-off-by: xufei <xufeixw@mail.ustc.edu.cn>
Signed-off-by: xufei <xufeixw@mail.ustc.edu.cn>
Signed-off-by: xufei <xufeixw@mail.ustc.edu.cn>
Signed-off-by: xufei <xufeixw@mail.ustc.edu.cn>
Signed-off-by: xufei <xufeixw@mail.ustc.edu.cn>
Signed-off-by: xufei <xufeixw@mail.ustc.edu.cn>
@ti-chi-bot ti-chi-bot bot merged commit 152db14 into pingcap:master Jun 14, 2024
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved lgtm ok-to-test release-note-none sig/planner SIG: Planner size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants