This is an automated email from the ASF dual-hosted git repository.
morrysnow pushed a commit to branch branch-3.1
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-3.1 by this push:
new 82debbac98b branch-3.1: [opt](nereids) use one instance per be to
execute simple query #53854 (#53922)
82debbac98b is described below
commit 82debbac98bb2f062970ee7e79494556b7f928db
Author: 924060929 <[email protected]>
AuthorDate: Mon Jul 28 14:14:20 2025 +0800
branch-3.1: [opt](nereids) use one instance per be to execute simple query
#53854 (#53922)
cherry pick from #53854
---
.../glue/translator/PhysicalPlanTranslator.java | 35 ++++++++++
.../org/apache/doris/planner/PlanFragment.java | 8 +++
.../org/apache/doris/nereids/util/PlanChecker.java | 11 +++
.../apache/doris/qe/NereidsCoordinatorTest.java | 78 ++++++++++++++++++++++
4 files changed, 132 insertions(+)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java
index 9f73343be6c..bdf09b135f3 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java
@@ -142,6 +142,7 @@ import
org.apache.doris.nereids.trees.plans.physical.PhysicalPartitionTopN;
import org.apache.doris.nereids.trees.plans.physical.PhysicalPlan;
import org.apache.doris.nereids.trees.plans.physical.PhysicalProject;
import org.apache.doris.nereids.trees.plans.physical.PhysicalQuickSort;
+import org.apache.doris.nereids.trees.plans.physical.PhysicalRelation;
import org.apache.doris.nereids.trees.plans.physical.PhysicalRepeat;
import org.apache.doris.nereids.trees.plans.physical.PhysicalResultSink;
import org.apache.doris.nereids.trees.plans.physical.PhysicalSchemaScan;
@@ -288,6 +289,14 @@ public class PhysicalPlanTranslator extends
DefaultPlanVisitor<PlanFragment, Pla
throw new RuntimeException(e.getMessage(), e);
}
}
+
+ if (isSimpleQuery(physicalPlan)) {
+ // the simple query maybe has two fragments or one fragment
+ rootFragment.setForceSingleInstance();
+ for (PlanFragment child : rootFragment.getChildren()) {
+ child.setForceSingleInstance();
+ }
+ }
return rootFragment;
}
@@ -2857,4 +2866,30 @@ public class PhysicalPlanTranslator extends
DefaultPlanVisitor<PlanFragment, Pla
}
return Lists.newArrayList();
}
+
+ // matching the simple query:
+ // 1. select xxx from tbl
+ // 2. select xxx from tbl where xxx=yyy
+ private boolean isSimpleQuery(PhysicalPlan root) {
+ if (!(root instanceof PhysicalResultSink)) {
+ return false;
+ }
+ Plan child = root.child(0);
+ if (child instanceof PhysicalLimit) {
+ child = child.child(0);
+ }
+ if (child instanceof PhysicalDistribute) {
+ child = child.child(0);
+ }
+ if (child instanceof PhysicalLimit) {
+ child = child.child(0);
+ }
+ if (child instanceof PhysicalProject) {
+ child = child.child(0);
+ }
+ if (child instanceof PhysicalFilter) {
+ child = child.child(0);
+ }
+ return child instanceof PhysicalRelation;
+ }
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/planner/PlanFragment.java
b/fe/fe-core/src/main/java/org/apache/doris/planner/PlanFragment.java
index d845b2bfc35..1124e4fbd5d 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/planner/PlanFragment.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/planner/PlanFragment.java
@@ -164,6 +164,7 @@ public class PlanFragment extends TreeNode<PlanFragment> {
public TQueryCacheParam queryCacheParam;
private int numBackends = 0;
+ private boolean forceSingleInstance = false;
/**
* C'tor for fragment with specific partition; the output is by default
broadcast.
@@ -320,6 +321,9 @@ public class PlanFragment extends TreeNode<PlanFragment> {
}
public int getParallelExecNum() {
+ if (forceSingleInstance) {
+ return 1;
+ }
return parallelExecNum;
}
@@ -522,4 +526,8 @@ public class PlanFragment extends TreeNode<PlanFragment> {
public boolean hasSerialScanNode() {
return planRoot.hasSerialScanChildren();
}
+
+ public void setForceSingleInstance() {
+ this.forceSingleInstance = true;
+ }
}
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/util/PlanChecker.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/util/PlanChecker.java
index 6962572d07a..140c83733fb 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/nereids/util/PlanChecker.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/util/PlanChecker.java
@@ -284,6 +284,17 @@ public class PlanChecker {
return this;
}
+ public NereidsPlanner plan(String sql) {
+ StatementContext statementContext = new
StatementContext(connectContext, new OriginStatement(sql, 0));
+ connectContext.setStatementContext(statementContext);
+ NereidsPlanner planner = new NereidsPlanner(statementContext);
+ LogicalPlan parsedPlan = new NereidsParser().parseSingle(sql);
+ LogicalPlanAdapter parsedPlanAdaptor = new
LogicalPlanAdapter(parsedPlan, statementContext);
+ statementContext.setParsedStatement(parsedPlanAdaptor);
+ planner.plan(parsedPlanAdaptor);
+ return planner;
+ }
+
public PlanChecker dpHypOptimize() {
double now = System.currentTimeMillis();
cascadesContext.getStatementContext().setDpHyp(true);
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/qe/NereidsCoordinatorTest.java
b/fe/fe-core/src/test/java/org/apache/doris/qe/NereidsCoordinatorTest.java
new file mode 100644
index 00000000000..c0fa25974fb
--- /dev/null
+++ b/fe/fe-core/src/test/java/org/apache/doris/qe/NereidsCoordinatorTest.java
@@ -0,0 +1,78 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.qe;
+
+import org.apache.doris.common.FeConstants;
+import org.apache.doris.nereids.NereidsPlanner;
+import org.apache.doris.nereids.util.PlanChecker;
+import org.apache.doris.planner.PlanFragment;
+import org.apache.doris.thrift.TUniqueId;
+import org.apache.doris.utframe.TestWithFeService;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+import java.util.UUID;
+
+public class NereidsCoordinatorTest extends TestWithFeService {
+ @BeforeAll
+ public void init() throws Exception {
+ FeConstants.runningUnitTest = true;
+
+ createDatabase("test");
+ useDatabase("test");
+
+ createTable("create table tbl(id int) distributed by hash(id) buckets
10 properties('replication_num' = '1');");
+ }
+
+ @Test
+ public void testSimpleQueryUseOneInstance() throws IOException {
+ ConnectContext connectContext = createDefaultCtx();
+ connectContext.getSessionVariable().parallelPipelineTaskNum = 10;
+ NereidsPlanner planner = plan("select * from test.tbl",
connectContext);
+ for (PlanFragment fragment : planner.getFragments()) {
+ Assertions.assertEquals(1, fragment.getParallelExecNum());
+ }
+
+ planner = plan("select * from test.tbl where id=1", connectContext);
+ for (PlanFragment fragment : planner.getFragments()) {
+ Assertions.assertEquals(1, fragment.getParallelExecNum());
+ }
+
+ planner = plan("select id, id + 1 from test.tbl where id = 2 limit 1",
connectContext);
+ for (PlanFragment fragment : planner.getFragments()) {
+ Assertions.assertEquals(1, fragment.getParallelExecNum());
+ }
+ }
+
+ private NereidsPlanner plan(String sql) throws IOException {
+ return plan(sql, createDefaultCtx());
+ }
+
+ private NereidsPlanner plan(String sql, ConnectContext connectContext)
throws IOException {
+
connectContext.getSessionVariable().setDisableNereidsRules("PRUNE_EMPTY_PARTITION,OLAP_SCAN_TABLET_PRUNE");
+ connectContext.setThreadLocalInfo();
+
+ UUID uuid = UUID.randomUUID();
+ connectContext.setQueryId(new TUniqueId(uuid.getMostSignificantBits(),
uuid.getLeastSignificantBits()));
+ NereidsPlanner planner = PlanChecker.from(connectContext).plan(sql);
+ return planner;
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]