Skip to content

HIVE-28489: Partition the input data of GroupBy with GroupingSet - #5424

Merged
okumin merged 7 commits into
apache:masterfrom
ngsg:HIVE-28489-PartitionDataBeforeGroupingSet
Nov 27, 2024
Merged

HIVE-28489: Partition the input data of GroupBy with GroupingSet#5424
okumin merged 7 commits into
apache:masterfrom
ngsg:HIVE-28489-PartitionDataBeforeGroupingSet

Conversation

@ngsg

@ngsg ngsg commented Aug 30, 2024

Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

This patch introduces a new optimization for GroupBy with GroupingSet. GroupingSet often emits too much rows and becomes a bottleneck of query execution. The proposed optimization tries mitigating this situation by reducing the cardinality of GroupBy key. For the detailed explanation, please checkout the slides attached in the JIRA page (HIVE-28489).

This patch introduces a new configuration key: hive.optimize.grouping.set.threshold. The default value of 1,000,000,000 is chosen because it showed best performance in 10TB TPC-DS experiment. Setting this value to negative number disables the optimization.

Why are the changes needed?

To improve query execution time of GroupBy with GroupingSet.

Does this PR introduce any user-facing change?

No

Is the change a dependency upgrade?

No

How was this patch tested?

We tested this patch using 10TB TPC-DS experiment. This patch contains a qfile test to verify optimized query plan.

@github-actions
github-actions Bot requested a review from abstractdog August 30, 2024 05:08
@ngsg
ngsg marked this pull request as draft August 30, 2024 06:11
@sonarqubecloud

sonarqubecloud Bot commented Sep 2, 2024

Copy link
Copy Markdown

@ngsg ngsg changed the title [WIP] HIVE-28489: Partition the input data of GroupBy with GroupingSet HIVE-28489: Partition the input data of GroupBy with GroupingSet Sep 3, 2024
@ngsg
ngsg marked this pull request as ready for review September 3, 2024 01:13

@BsoBird BsoBird left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It seems like there are no major issues. However, it would be best to have a few more people review it together.

import org.apache.hadoop.hive.ql.plan.ColStatistics;
import org.apache.hadoop.hive.ql.plan.ExprNodeColumnDesc;
import org.apache.hadoop.hive.ql.plan.ExprNodeDesc;
import org.apache.hadoop.hive.ql.plan.ExprNodeFieldDesc;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Remove unused import entries.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

removed an unused import.

@okumin

okumin commented Nov 13, 2024

Copy link
Copy Markdown
Contributor

The intention is admirable, but I am not 100% confident that this is the best approach because I need to know how GROUPING SETS works. It still needs time for me

@BsoBird

BsoBird commented Nov 15, 2024

Copy link
Copy Markdown
Contributor

The intention is admirable, but I am not 100% confident that this is the best approach because I need to know how GROUPING SETS works. It still needs time for me

Hello. @okumin Trino seems to have adopted a similar scheme to optimize grouping sets. It appears that the modifications in this submission are intended to port the optimization rules from Trino to HIVE. Since Trino has been using this rule for a long time, and we have received positive feedback from users after introducing this patch, I personally believe that the approach used in this submission is a viable solution. After all, if we find a better solution, it would be quite easy for us to replace the changes introduced by this PR.

Comment thread ql/src/java/org/apache/hadoop/hive/ql/parse/TezCompiler.java Outdated
Comment thread ql/src/java/org/apache/hadoop/hive/ql/optimizer/GroupingSetOptimizer.java Outdated
Comment thread ql/src/java/org/apache/hadoop/hive/ql/optimizer/GroupingSetOptimizer.java Outdated
Comment thread ql/src/java/org/apache/hadoop/hive/ql/optimizer/GroupingSetOptimizer.java Outdated

TableDesc keyTable = PlanUtils.getReduceKeyTableDesc(new ArrayList<>(), "", "");

List<ExprNodeDesc> keyColumns = new ArrayList<>();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I could be wrong. Should we also use the partition key as a sort key to optimize the hash table utilization? I see we already achieved a good result with this implementation, so I might be wrong.
If we do that, I wonder if we can generalize the utility to insert REDUCE_SINK + SEL somewhere because it is a useful conversion...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I agree that inserting RS + SEL might be useful optimization if we can find the place where heavy sort happens. However, I'm not sure whether HashTable can fully take advantage of pre-sorting.
I'll test your idea in our cluster and share the result later on.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@okumin

I tested your idea using 10TB TPC-DS dataset. I used query18, query22, query67 and set hive.optimize.grouping.set.threshold to 1,000,000,000. I ran each query 3 times.

query18 query22 query67
# GBY input rows estimation 382,977,011 258,698,384 5,279,977,323
# GBY output rows estimation 1,914,885,055 1,293,491,920 47,519,795,907
Query execution time(current impl.) 27.575, 24.089, 23.265 14.827, 13.925, 12.959 426.62, 419.793, 414.403
Query execution time(with additional sort) 27.636, 24.836, 24.054 16.531, 15.729, 15.624 318.425, 323.733, 336.545

There is almost no change in the query execution time of relatively small GroupBys (query18 and query22). However, it appears that a large GroupBy benefits from the additional sort. Therefore, I conclude that adding a sort before large GroupBys is worthwhile. The latest commit(efe982c) includes an implementation of additional sort that I used for the test.

Comment thread ql/src/java/org/apache/hadoop/hive/ql/optimizer/GroupingSetOptimizer.java Outdated
Comment thread ql/src/java/org/apache/hadoop/hive/ql/optimizer/GroupingSetOptimizer.java Outdated
@okumin

okumin commented Nov 18, 2024

Copy link
Copy Markdown
Contributor

@BsoBird Thanks. Could you give us a document or equivalent implementation of Trino?

@okumin okumin left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Mostly, looks good to me based on my experience. Only one comment.

int numReducers = Utilities.estimateReducers(
parentOp.getStatistics().getDataSize(), context.bytesPerReducer, context.maxReducers, false);

ReduceSinkDesc rsConf = new ReduceSinkDesc(keyColumns, 0, valueColumns, keyColumnNames,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I guess the second argument should be keyColumns.size()

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

You're right. Fixed it to use keyColumns.size().

@okumin okumin left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

+1

@sonarqubecloud

Copy link
Copy Markdown

@okumin
okumin merged commit 6e9c828 into apache:master Nov 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants