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

Allow parallel replicas for JOIN with analyzer [part 2] #58916

Merged

Conversation

KochetovNicolai
Copy link
Member

@KochetovNicolai KochetovNicolai commented Jan 17, 2024

Changelog category (leave one):

  • Improvement

Changelog entry (a user-readable short description of the changes that goes to CHANGELOG.md):

Support LEFT JOIN, ALL INNER JOIN, and simple subqueries for parallel replicas (only with analyzer). New setting parallel_replicas_prefer_local_join chooses local JOIN execution (by default) vs GLOBAL JOIN. All tables should exist on every replica from cluster_for_parallel_replicas. New settings min_external_table_block_size_rows and min_external_table_block_size_bytes are used to squash small blocks that are sent for temporary tables (only with analyzer).

@robot-clickhouse-ci-1 robot-clickhouse-ci-1 added the pr-improvement Pull request with some product improvements label Jan 17, 2024
@robot-clickhouse-ci-1
Copy link
Contributor

robot-clickhouse-ci-1 commented Jan 17, 2024

This is an automated comment for commit 03720d5 with description of existing statuses. It's updated for the latest CI running

⏳ Click here to open a full report in a separate page

Successful checks
Check nameDescriptionStatus
Docs checkBuilds and tests the documentation✅ success
Fast testNormally this is the first check that is ran for a PR. It builds ClickHouse and runs most of stateless functional tests, omitting some. If it fails, further checks are not started until it is fixed. Look at the report to see which tests fail, then reproduce the failure locally as described here✅ success
Mergeable CheckChecks if all other necessary checks are successful✅ success
Style checkRuns a set of checks to keep the code style clean. If some of tests failed, see the related log from the report✅ success
Check nameDescriptionStatus
CI runningA meta-check that indicates the running CI. Normally, it's in success or pending state. The failed status indicates some problems with the PR⏳ pending

@KochetovNicolai KochetovNicolai changed the title Allow parallel replicas for join with analyzer [part 2] Allow parallel replicas for JOIN with analyzer [part 2] Jan 17, 2024
@novikd novikd self-assigned this Jan 18, 2024
@KochetovNicolai KochetovNicolai force-pushed the allow-parallel-replicas-for-join-with-analyzer-2 branch from a19db02 to ec0fce3 Compare January 18, 2024 13:20
@KochetovNicolai KochetovNicolai force-pushed the allow-parallel-replicas-for-join-with-analyzer-2 branch from ec0fce3 to 6bf28c8 Compare January 29, 2024 14:11
@KochetovNicolai KochetovNicolai force-pushed the allow-parallel-replicas-for-join-with-analyzer-2 branch from cba10d7 to 29780b1 Compare February 5, 2024 17:07
@KochetovNicolai KochetovNicolai marked this pull request as ready for review February 6, 2024 15:59
Copy link
Member

@novikd novikd left a comment

Choose a reason for hiding this comment

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

In general LGTM

Comment on lines +154 to +159
auto ast = queryNodeToSelectQuery(query_node);
/// Remove CTEs information from distributed queries.
/// Now, if cte_name is set for subquery node, AST -> String serialization will only print cte name.
/// But CTE is defined only for top-level query part, so may not be sent.
/// Removing cte_name forces subquery to be always printed.
removeCTEs(ast);
Copy link
Member

Choose a reason for hiding this comment

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

Maybe better to add a flag to ConvertToASTOptions and do not add CTEs in QueryNode::toASTImpl at all?

Copy link
Member Author

Choose a reason for hiding this comment

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

I've tried, but it did not work for some reason.
Will do it later.

class GlobalPlannerContext
{
public:
GlobalPlannerContext() = default;
explicit GlobalPlannerContext(const QueryNode * parallel_replicas_node_, const TableNode * parallel_replicas_table_)
Copy link
Member

Choose a reason for hiding this comment

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

Please, add a comment here.

Copy link
Member Author

Choose a reason for hiding this comment

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

There is a comment below ... Should I add another one?

Comment on lines +49 to +54
/// The query which will be executed with parallel replicas.
/// In case if only the most inner subquery can be executed with parallel replicas, node is nullptr.
const QueryNode * const parallel_replicas_node = nullptr;
/// Table which is used with parallel replicas reading. Now, only one table is supported by the protocol.
/// It is the left-most table of the query (in JOINs, UNIONs and subqueries).
const TableNode * const parallel_replicas_table = nullptr;
Copy link
Member

Choose a reason for hiding this comment

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

Is it really necessary in global context?

Copy link
Member Author

Choose a reason for hiding this comment

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

Discussed it. Could not find a better place so far.

Comment on lines +412 to +413
CollectStoragesVisitor collect_storages;
collect_storages.visit(node);
Copy link
Member

Choose a reason for hiding this comment

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

This is not optimal and lead to O(N^2) traversal. It's better to collect this info in enterImpl and make check in leaveImpl. We can leave it as it, but it's better to rewrite it in the follow up PR.

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't see why.
We traverse only the left table expression in RewriteJoinToGlobalJoinVisitor, but check allStoragesAreMergeTree only for the right table expressions.


/// Find a qury which can be executed with parallel replicas up to WithMergableStage.
/// Returned query will always contain some (>1) subqueries, possibly with joins.
const QueryNode * findParallelReplicasQuery(const QueryTreeNodePtr & query_tree_node, SelectQueryOptions & select_query_options);
Copy link
Member

Choose a reason for hiding this comment

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

Maybe better to call it findQueryForParallelReplicas?

return res;
}

static const TableNode * findTableForParallelReplicas(const IQueryTreeNode * query_tree_node)
Copy link
Member

Choose a reason for hiding this comment

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

I'd prefer to have a non recursive implementation.

Copy link
Member Author

Choose a reason for hiding this comment

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

Agree.
However, it would make sense if we rewrite all the visitors to non-recursive mode implementation :)

@nikitamikhaylov
Copy link
Member

@KochetovNicolai Please add new settings to the history

┌─name────────────────────────────────┐
│ min_external_table_block_size_rows  │
│ min_external_table_block_size_bytes │
│ parallel_replicas_prefer_local_join │
└─────────────────────────────────────┘

@KochetovNicolai
Copy link
Member Author

@nikitamikhaylov I've added it a long time ago. Looks like the check is broken somehow.

@KochetovNicolai
Copy link
Member Author

Build is green. Merging.

@KochetovNicolai KochetovNicolai merged commit ebf47dd into master Feb 14, 2024
16 of 37 checks passed
@KochetovNicolai KochetovNicolai deleted the allow-parallel-replicas-for-join-with-analyzer-2 branch February 14, 2024 12:30
@robot-ch-test-poll3 robot-ch-test-poll3 added the pr-synced-to-cloud The PR is synced to the cloud repo label Feb 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pr-backports-created-cloud pr-improvement Pull request with some product improvements pr-must-backport-cloud pr-synced-to-cloud The PR is synced to the cloud repo
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants