-
Notifications
You must be signed in to change notification settings - Fork 756
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
feat: hilbert clustering #17045
Merged
Merged
feat: hilbert clustering #17045
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
github-actions
bot
added
the
pr-feature
this PR introduces a new feature to the codebase
label
Dec 12, 2024
zhyass
force-pushed
the
feature_cluster_table
branch
5 times, most recently
from
December 30, 2024 13:51
88111a3
to
059bb42
Compare
Maybe should add performance test with hilbert clustering? |
zhyass
added
ci-cloud
Build docker image for cloud test
and removed
ci-cloud
Build docker image for cloud test
labels
Dec 31, 2024
zhyass
force-pushed
the
feature_cluster_table
branch
2 times, most recently
from
January 1, 2025 09:02
e5ea1e6
to
595cff9
Compare
zhyass
force-pushed
the
feature_cluster_table
branch
from
January 2, 2025 04:25
6ba61fd
to
c0c2183
Compare
zhyass
added
ci-cloud
Build docker image for cloud test
and removed
ci-cloud
Build docker image for cloud test
labels
Jan 2, 2025
zhyass
force-pushed
the
feature_cluster_table
branch
2 times, most recently
from
January 2, 2025 16:43
b336e03
to
ffdc058
Compare
zhyass
force-pushed
the
feature_cluster_table
branch
from
January 6, 2025 09:36
5d22310
to
933d544
Compare
zhyass
added
ci-cloud
Build docker image for cloud test
and removed
ci-cloud
Build docker image for cloud test
labels
Jan 6, 2025
zhyass
force-pushed
the
feature_cluster_table
branch
from
January 7, 2025 02:38
933d544
to
07a64c0
Compare
zhyass
added
ci-cloud
Build docker image for cloud test
and removed
ci-cloud
Build docker image for cloud test
labels
Jan 7, 2025
Docker Image for PR
|
zhyass
force-pushed
the
feature_cluster_table
branch
from
January 9, 2025 03:53
a99f13b
to
3b6e513
Compare
dantengsky
reviewed
Jan 9, 2025
dantengsky
reviewed
Jan 9, 2025
dantengsky
reviewed
Jan 9, 2025
dantengsky
approved these changes
Jan 11, 2025
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
ci-cloud
Build docker image for cloud test
pr-feature
this PR introduces a new feature to the codebase
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
I hereby agree to the terms of the CLA available at: https://docs.databend.com/dev/policies/cla/
Summary
This PR refines Hilbert clustering in Databend by adopting a range-based partitioning approach. It samples cluster keys, assigns range partition IDs, and calculates Hilbert indexes for efficient pruning and clustering. Key changes include:
Removing the old Hilbert clustering logic.
Stable segments are excluded from reclustering to preserve optimal clustering results.
The
alter table t recluster
is equivalent toTest
Prepare data.
test_hilbert
with the new hilbert cluster type.test_hilbert_old
is the old hilbert cluster type table.test_linear
is the normal linear cluster type table.Contains 600000000 rows.
Explain: (pruning stats, query duration, size)
1. id = 1004050502160506553
test_linear
:segments: <range pruning: 2 to 2>, blocks: <range pruning: 2211 to 12, bloom pruning: 12 to 1>
198ms 5.61MB
test_hilbert_old
:segments: <range pruning: 2 to 2>, blocks: <range pruning: 2246 to 45, bloom pruning: 45 to 2>
199ms 7.39MB
test_hilbert
:segments: <range pruning: 2 to 2>, blocks: <range pruning: 2388 to 79, bloom pruning: 79 to 1>
163ms 3.77MB
2. insert_time = '2024-11-27 18:48:25.619751'
test_linear
:**segments: <range pruning: 2 to 2>, blocks: <range pruning: 2211 to 2211, bloom pruning: 2211 to 12> **
431ms 49.02MB
test_hilbert_old
:**segments: <range pruning: 2 to 2>, blocks: <range pruning: 2246 to 884, bloom pruning: 884 to 7> **
331ms 29.31MB
test_hilbert
:segments: <range pruning: 2 to 2>, blocks: <range pruning: 2388 to 77, bloom pruning: 77 to 1>
238ms 3.73MB
3. id = 7190230217165929558 and insert_time = '2024-11-27 18:48:25.619751'
test_linear
:segments: <range pruning: 2 to 2>, blocks: <range pruning: 2211 to 14, bloom pruning: 14 to 1>
165ms 4.9MB
test_hilbert_old
:**segments: <range pruning: 2 to 2>, blocks: <range pruning: 2246 to 32, bloom pruning: 32 to 1> **
157ms 4.45MB
test_hilbert
:**segments: <range pruning: 2 to 2>, blocks: <range pruning: 2388 to 2, bloom pruning: 2 to 1> **
149ms 3.73MB
4. id = 7190230217165929558 and insert_time >= '2022-08-04 05:38:53.865252' and insert_time <= '2025-01-01 12:12:12.000000'
test_linear
:segments: <range pruning: 2 to 2>, blocks: <range pruning: 2211 to 14, bloom pruning: 14 to 1>
140ms 4.9MB
test_hilbear_old
:segments: <range pruning: 2 to 2>, blocks: <range pruning: 2246 to 32, bloom pruning: 32 to 1>
157ms 4.45MB
test_hilbert
:segments: <range pruning: 2 to 2>, blocks: <range pruning: 2388 to 2, bloom pruning: 2 to 1>
142ms 3.73MB
5. 5. id >= 0 and id <= 100000000000000 and insert_time >= '2022-08-04 05:38:53.865252' and insert_time <= '2025-01-01 12:12:12.000000'
test_linear
:segments: <range pruning: 2 to 2>, blocks: <range pruning: 2211 to 13>
338ms 59.84MB
test_hilbear_old
:**segments: <range pruning: 2 to 2>, blocks: <range pruning: 2246 to 18> **
348ms 76.53MB
test_hilbert
:segments: <range pruning: 2 to 2>, blocks: <range pruning: 2388 to 2>
189ms 7.49MB
6. insert_time >= '2022-08-04 05:38:53.865252' and insert_time <= '2025-01-01 12:12:12.000000'
test_linear
:segments: <range pruning: 2 to 2>, blocks: <range pruning: 2211 to 2211>
2.2s 566.16MB
test_hilbear_old
:segments: <range pruning: 2 to 2>, blocks: <range pruning: 2246 to 884>
1.1s 209.28MB
test_hilbert
:segments: <range pruning: 2 to 2>, blocks: <range pruning: 2388 to 77>
451ms 22.8MB
7. id >= 0 and id <= 100000000000000
test_linear
:segments: <range pruning: 2 to 2>, blocks: <range pruning: 2211 to 13>
337ms 59.84MB
test_hilbert_old
:segments: <range pruning: 2 to 2>, blocks: <range pruning: 2246 to 41>
715ms 172.72MB
test_hilbert
:segments: <range pruning: 2 to 2>, blocks: <range pruning: 2388 to 73>
1.1s 279.91MB
Conclusions
The optimized Hilbert Clustering demonstrates superior performance over Linear Clustering and the previous version of Hilbert Clustering in most scenarios, especially when query conditions involve cluster key columns other than the first one. However, its performance is slightly weaker when query conditions include only the first cluster key column.
This new version effectively resolves the performance degradation caused by uneven data distribution in the older Hilbert Clustering. A critical point to note is that the optimized Hilbert Clustering performs reclustering on a per-segment basis, potentially involving over 100GB of data, which significantly increases the likelihood of triggering sort spill. As a result, single recluster operations may take longer compared to the previous version, making it unsuitable for automatic reclustering immediately after data ingestion. However, the optimized version has a clear advantage in reducing execution time during the final reclustering phase compared to its predecessor.
It is important to note that although Linear Clustering also uses a localized recluster strategy, it processes max_threads * 4 segments at a time, whereas Hilbert Clustering handles only one segment per operation. This limitation in localized reclustering could become more pronounced under extreme conditions. Therefore, Hilbert Clustering is better suited for scenarios where data ingestion follows a certain order, such as chronological order.
Tests
Type of change
This change is