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

feat: prune partitions by internal column predicates. #11248

Merged
merged 10 commits into from
Apr 28, 2023

Conversation

RinChanNOWWW
Copy link
Contributor

@RinChanNOWWW RinChanNOWWW commented Apr 26, 2023

I hereby agree to the terms of the CLA available at: https://databend.rs/dev/policies/cla/

Summary

If there are internal columns in predicates (WHERE clause), we can prune partitions by this information.

mysql> explain select watchid from hits where  _segment_name = '1/150452/_sg/6d87fc741d4c4a5fb5e94786d4bc023d_v3.bincode';
+-------------------------------------------------------------------------------------------------------------------------------------------+
| explain                                                                                                                                   |
+-------------------------------------------------------------------------------------------------------------------------------------------+
| EvalScalar                                                                                                                                |
| ├── expressions: [hits.watchid (#0)]                                                                                                      |
| ├── estimated rows: 33332499.00                                                                                                           |
| └── Filter                                                                                                                                |
|     ├── filters: [_segment_name (#105) = '1/150452/_sg/6d87fc741d4c4a5fb5e94786d4bc023d_v3.bincode']                                      |
|     ├── estimated rows: 33332499.00                                                                                                       |
|     └── TableScan                                                                                                                         |
|         ├── table: default.default.hits                                                                                                   |
|         ├── read rows: 2457416                                                                                                            |
|         ├── read bytes: 19661141                                                                                                          |
|         ├── partitions total: 770                                                                                                         |
|         ├── partitions scanned: 19                                                                                                        |
|         ├── pruning stats: [segments: <range pruning: 1 to 1>, blocks: <range pruning: 19 to 19, bloom pruning: 19 to 19>]                |
|         ├── push downs: [filters: [_segment_name (#105) = '1/150452/_sg/6d87fc741d4c4a5fb5e94786d4bc023d_v3.bincode'], limit: NONE]       |
|         ├── output columns: [watchid, _segment_name]                                                                                      |
|         └── estimated rows: 99997497.00                                                                                                   |
+-------------------------------------------------------------------------------------------------------------------------------------------+

mysql> explain select watchid from hits where  _segment_name = '1/150452/_sg/6d87fc741d4c4a5fb5e94786d4bc023d_v3.bincode' and _block_name = '1/150452/_b/b3892fa880234074a17bb7d114c52df3_v2.parquet';
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| explain                                                                                                                                                                                                                                                                            |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| EvalScalar                                                                                                                                                                                                                                                                         |
| ├── expressions: [hits.watchid (#0)]                                                                                                                                                                                                                                               |
| ├── estimated rows: 11110833.00                                                                                                                                                                                                                                                    |
| └── Filter                                                                                                                                                                                                                                                                         |
|     ├── filters: [_segment_name (#105) = '1/150452/_sg/6d87fc741d4c4a5fb5e94786d4bc023d_v3.bincode', _block_name (#106) = '1/150452/_b/b3892fa880234074a17bb7d114c52df3_v2.parquet']                                                                                               |
|     ├── estimated rows: 11110833.00                                                                                                                                                                                                                                                |
|     └── TableScan                                                                                                                                                                                                                                                                  |
|         ├── table: default.default.hits                                                                                                                                                                                                                                            |
|         ├── read rows: 136441                                                                                                                                                                                                                                                      |
|         ├── read bytes: 1091630                                                                                                                                                                                                                                                    |
|         ├── partitions total: 770                                                                                                                                                                                                                                                  |
|         ├── partitions scanned: 1                                                                                                                                                                                                                                                  |
|         ├── pruning stats: [segments: <range pruning: 1 to 1>, blocks: <range pruning: 1 to 1, bloom pruning: 1 to 1>]                                                                                                                                                             |
|         ├── push downs: [filters: [and_filters(CAST(_segment_name (#105) = '1/150452/_sg/6d87fc741d4c4a5fb5e94786d4bc023d_v3.bincode' AS Boolean NULL), CAST(_block_name (#106) = '1/150452/_b/b3892fa880234074a17bb7d114c52df3_v2.parquet' AS Boolean NULL))], limit: NONE]       |
|         ├── output columns: [watchid, _segment_name, _block_name]                                                                                                                                                                                                                  |
|         └── estimated rows: 99997497.00                                                                                                                                                                                                                                            |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

mysql> explain select _segment_name from hits where substring(_segment_name, -7) = 'xxx' limit 10;
+------------------------------------------------------------------------------------------------------+
| explain                                                                                              |
+------------------------------------------------------------------------------------------------------+
| EvalScalar                                                                                           |
| ├── expressions: [_segment_name (#105)]                                                              |
| ├── estimated rows: 10.00                                                                            |
| └── Limit                                                                                            |
|     ├── limit: 10                                                                                    |
|     ├── offset: 0                                                                                    |
|     ├── estimated rows: 10.00                                                                        |
|     └── Filter                                                                                       |
|         ├── filters: [substr(_segment_name (#105), -7) = 'xxx']                                      |
|         ├── estimated rows: 33332499.00                                                              |
|         └── TableScan                                                                                |
|             ├── table: default.default.hits                                                          |
|             ├── read rows: 0                                                                         |
|             ├── read bytes: 0                                                                        |
|             ├── partitions total: 770                                                                |
|             ├── partitions scanned: 0                                                                |
|             ├── push downs: [filters: [substr(_segment_name (#105), -7) = 'xxx'], limit: NONE]       |
|             ├── output columns: [_segment_name]                                                      |
|             └── estimated rows: 99997497.00                                                          |
+------------------------------------------------------------------------------------------------------+

LIMITS:

  • Only _segment_name and _block_name are supported.
  • If one predicate (each part of the conjunction) does not only contain the internal column, it's invalid for pruning. For example,
select * from t where t.a = _block_name and substring(_segment_name, -10) = 'v3.bincode;'

, the first predicate is invalid while the second one is valid.

@vercel
Copy link

vercel bot commented Apr 26, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

1 Ignored Deployment
Name Status Preview Comments Updated (UTC)
databend ⬜️ Ignored (Inspect) Visit Preview Apr 28, 2023 1:25pm

@mergify mergify bot added the pr-feature this PR introduces a new feature to the codebase label Apr 26, 2023
@sundy-li
Copy link
Member

sundy-li commented Apr 26, 2023

_segment_name seems to be too long, how about making it just be file name without prefixes and suffixes, like 6d87fc741d4c4a5fb5e94786d4bc023d_v3

@RinChanNOWWW RinChanNOWWW marked this pull request as draft April 27, 2023 04:27
@RinChanNOWWW RinChanNOWWW marked this pull request as ready for review April 27, 2023 09:04
@RinChanNOWWW RinChanNOWWW force-pushed the prune-by-internal-columns branch from ff336af to f6cb7c4 Compare April 27, 2023 09:22
@BohuTANG BohuTANG merged commit 1e8153b into databendlabs:main Apr 28, 2023
@RinChanNOWWW RinChanNOWWW deleted the prune-by-internal-columns branch June 13, 2023 02:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pr-feature this PR introduces a new feature to the codebase
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants