This is an automated email from the ASF dual-hosted git repository.

jackietien pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/master by this push:
     new 67fda53e0c1 feat: show timeseries [order by timseries] clause (#17065)
67fda53e0c1 is described below

commit 67fda53e0c11e341639948bec495f96ff1483f3f
Author: xiangmy21 <[email protected]>
AuthorDate: Fri Feb 6 11:41:04 2026 +0800

    feat: show timeseries [order by timseries] clause (#17065)
---
 .../IoTDBShowTimeseriesOrderByTimeseriesIT.java    | 278 +++++++++++++++++++++
 .../org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4   |   9 +-
 .../impl/DataNodeInternalRPCServiceImpl.java       |  16 +-
 .../schema/source/LogicalViewSchemaSource.java     |   3 +-
 .../schema/source/SchemaSourceFactory.java         |  16 +-
 .../schema/source/TimeSeriesSchemaSource.java      |   9 +-
 .../db/queryengine/plan/parser/ASTVisitor.java     |  10 +
 .../plan/planner/LogicalPlanBuilder.java           |   8 +-
 .../plan/planner/LogicalPlanVisitor.java           |  69 +++--
 .../plan/planner/OperatorTreeGenerator.java        |   3 +-
 .../SimpleFragmentParallelPlanner.java             |   4 +-
 .../metadata/read/TimeSeriesSchemaScanNode.java    |  49 +++-
 .../node/process/ActiveRegionScanMergeNode.java    |   3 +
 .../plan/statement/metadata/ShowStatement.java     |   7 +
 .../metadata/ShowTimeSeriesStatement.java          |  15 ++
 .../apache/iotdb/db/schemaengine/SchemaEngine.java |  21 ++
 .../schemaregion/impl/SchemaRegionMemoryImpl.java  |   8 +
 .../mtree/impl/mem/MTreeBelowSGMemoryImpl.java     | 198 +++++++++++++--
 .../mtree/impl/mem/mnode/IMemMNode.java            |  11 +-
 .../mtree/impl/mem/mnode/basic/BasicMNode.java     |  16 +-
 .../impl/mem/mnode/impl/AboveDatabaseMNode.java    |  10 +
 .../mtree/impl/mem/mnode/impl/DatabaseMNode.java   |  10 +
 .../impl/mem/mnode/impl/MeasurementMNode.java      |  10 +
 .../mtree/impl/pbtree/MTreeBelowSGCachedImpl.java  | 148 +++++++++++
 .../schemaregion/read/req/IShowTimeSeriesPlan.java |   4 +
 .../read/req/SchemaRegionReadPlanFactory.java      |  14 +-
 .../read/req/impl/ShowTimeSeriesPlanImpl.java      |  18 +-
 .../impl/SchemaReaderLimitOffsetWrapper.java       |  36 ++-
 .../template/ClusterTemplateManager.java           |   8 +-
 .../schemaRegion/SchemaRegionTestUtil.java         |  25 +-
 .../schema/SchemaQueryScanOperatorTest.java        |   3 +-
 31 files changed, 951 insertions(+), 88 deletions(-)

diff --git 
a/integration-test/src/test/java/org/apache/iotdb/db/it/schema/IoTDBShowTimeseriesOrderByTimeseriesIT.java
 
b/integration-test/src/test/java/org/apache/iotdb/db/it/schema/IoTDBShowTimeseriesOrderByTimeseriesIT.java
new file mode 100644
index 00000000000..8218d9ef511
--- /dev/null
+++ 
b/integration-test/src/test/java/org/apache/iotdb/db/it/schema/IoTDBShowTimeseriesOrderByTimeseriesIT.java
@@ -0,0 +1,278 @@
+/*
+ * 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.iotdb.db.it.schema;
+
+import org.apache.iotdb.commons.schema.column.ColumnHeaderConstant;
+import org.apache.iotdb.it.env.EnvFactory;
+import org.apache.iotdb.itbase.category.ClusterIT;
+import org.apache.iotdb.itbase.category.LocalStandaloneIT;
+import org.apache.iotdb.util.AbstractSchemaIT;
+
+import org.junit.After;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runners.Parameterized;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+@Category({LocalStandaloneIT.class, ClusterIT.class})
+public class IoTDBShowTimeseriesOrderByTimeseriesIT extends AbstractSchemaIT {
+
+  private static final List<String> BASE_TIMESERIES_DB1 =
+      Arrays.asList("root.db1.devA.m1", "root.db1.devB.m1", 
"root.db1.devA.m2", "root.db1.devB.x");
+  private static final List<String> BASE_TIMESERIES_DB2 =
+      Arrays.asList("root.db2.devA.m1", "root.db2.devC.m3", 
"root.db2.devC.m0");
+  private static final List<String> BASE_TIMESERIES = // combine db1 and db2
+      Stream.concat(BASE_TIMESERIES_DB1.stream(), BASE_TIMESERIES_DB2.stream())
+          .collect(Collectors.toList());
+
+  public IoTDBShowTimeseriesOrderByTimeseriesIT(SchemaTestMode schemaTestMode) 
{
+    super(schemaTestMode);
+  }
+
+  @Parameterized.BeforeParam
+  public static void before() throws Exception {
+    setUpEnvironment();
+    EnvFactory.getEnv().initClusterEnvironment();
+  }
+
+  @Parameterized.AfterParam
+  public static void after() throws Exception {
+    EnvFactory.getEnv().cleanClusterEnvironment();
+    tearDownEnvironment();
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    clearSchema();
+  }
+
+  private void prepareComplexSchema() throws Exception {
+    try (Connection connection = EnvFactory.getEnv().getConnection();
+        Statement statement = connection.createStatement()) {
+      statement.execute("CREATE DATABASE root.db1");
+      statement.execute("CREATE DATABASE root.db2");
+
+      for (String ts : BASE_TIMESERIES) {
+        statement.execute(
+            String.format(
+                "create timeseries %s with datatype=INT32, encoding=RLE, 
compression=SNAPPY", ts));
+      }
+    }
+  }
+
+  private List<String> queryTimeseries(final String sql) throws Exception {
+    try (Connection connection = EnvFactory.getEnv().getConnection();
+        Statement statement = connection.createStatement();
+        ResultSet resultSet = statement.executeQuery(sql)) {
+      List<String> result = new ArrayList<>();
+      while (resultSet.next()) {
+        result.add(resultSet.getString(ColumnHeaderConstant.TIMESERIES));
+      }
+      return result;
+    }
+  }
+
+  @Test
+  public void testOrderAscWithoutLimit() throws Exception {
+    prepareComplexSchema();
+    List<String> expected = new ArrayList<>(BASE_TIMESERIES);
+    Collections.sort(expected);
+
+    List<String> actual = queryTimeseries("show timeseries root.db*.** order 
by timeseries");
+    assertEquals(expected, actual);
+  }
+
+  @Test
+  public void testOrderDescWithOffsetLimit() throws Exception {
+    prepareComplexSchema();
+    List<String> expected = new ArrayList<>(BASE_TIMESERIES_DB1);
+    Collections.sort(expected);
+    Collections.reverse(expected);
+    expected = expected.subList(1, 3); // offset 1 limit 2
+
+    List<String> actual =
+        queryTimeseries("show timeseries root.db1.** order by timeseries desc 
offset 1 limit 2");
+    assertEquals(expected, actual);
+  }
+
+  @Test
+  public void testInsertThenQueryOrder() throws Exception {
+    prepareComplexSchema();
+    try (Connection connection = EnvFactory.getEnv().getConnection();
+        Statement statement = connection.createStatement()) {
+      statement.execute(
+          "create timeseries root.db1.devX.a with datatype=INT32, 
encoding=RLE, compression=SNAPPY");
+    }
+
+    List<String> expected = new ArrayList<>(BASE_TIMESERIES_DB1);
+    expected.add("root.db1.devX.a");
+    Collections.sort(expected);
+
+    List<String> actual = queryTimeseries("show timeseries root.db1.** order 
by timeseries");
+    assertEquals(expected, actual);
+  }
+
+  @Test
+  public void testDeleteSubtreeThenQueryOrder() throws Exception {
+    prepareComplexSchema();
+    try (Connection connection = EnvFactory.getEnv().getConnection();
+        Statement statement = connection.createStatement()) {
+      statement.execute("delete timeseries root.db2.devC.**");
+    }
+
+    List<String> expected = new ArrayList<>(BASE_TIMESERIES_DB2);
+    expected.remove("root.db2.devC.m0");
+    expected.remove("root.db2.devC.m3");
+    Collections.sort(expected);
+
+    List<String> actual = queryTimeseries("show timeseries root.db2.** order 
by timeseries");
+    assertEquals(expected, actual);
+  }
+
+  @Test
+  public void testOffsetLimitAfterDeletesAndAdds() throws Exception {
+    prepareComplexSchema();
+    try (Connection connection = EnvFactory.getEnv().getConnection();
+        Statement statement = connection.createStatement()) {
+      statement.execute("delete timeseries root.db1.devB.x");
+      statement.execute(
+          "create timeseries root.db1.devC.m0 with datatype=INT32, 
encoding=RLE, compression=SNAPPY");
+      statement.execute(
+          "create timeseries root.db1.devZ.z with datatype=INT32, 
encoding=RLE, compression=SNAPPY");
+    }
+
+    List<String> expected = new ArrayList<>(BASE_TIMESERIES_DB1);
+    expected.remove("root.db1.devB.x");
+    expected.add("root.db1.devC.m0");
+    expected.add("root.db1.devZ.z");
+    Collections.sort(expected);
+    expected = expected.subList(2, 4); // offset 2 limit 2
+
+    List<String> actual =
+        queryTimeseries("show timeseries root.db1.** order by timeseries 
offset 2 limit 2");
+    assertEquals(expected, actual);
+  }
+
+  @Test
+  public void testConflictWithLatest() throws Exception {
+    prepareComplexSchema();
+    try (Connection connection = EnvFactory.getEnv().getConnection();
+        Statement statement = connection.createStatement()) {
+      try (ResultSet ignored =
+          statement.executeQuery("show latest timeseries order by 
timeseries")) {
+        fail("Expected exception for conflict between LATEST and ORDER BY 
TIMESERIES");
+      } catch (SQLException e) {
+        assertTrue(
+            e.getMessage().toLowerCase().contains("latest")
+                && e.getMessage().toLowerCase().contains("order by 
timeseries"));
+      }
+    }
+  }
+
+  @Test
+  public void testOrderByWithTimeCondition() throws Exception {
+    try (Connection connection = EnvFactory.getEnv().getConnection();
+        Statement statement = connection.createStatement()) {
+      statement.execute("CREATE DATABASE root.db1");
+      statement.execute(
+          "create timeseries root.db1.devA.s1 with datatype=INT32, 
encoding=RLE, compression=SNAPPY");
+      statement.execute(
+          "create timeseries root.db1.devA.s2 with datatype=INT32, 
encoding=RLE, compression=SNAPPY");
+      statement.execute(
+          "create timeseries root.db1.devB.s1 with datatype=INT32, 
encoding=RLE, compression=SNAPPY");
+
+      // s1 has points in [1..5], s2 only [1..3], devB.s1 only [4..5]
+      for (int t = 1; t <= 5; t++) {
+        statement.execute(
+            String.format("insert into root.db1.devA(timestamp, s1) values 
(%d, %d)", t, t));
+      }
+      for (int t = 1; t <= 3; t++) {
+        statement.execute(
+            String.format("insert into root.db1.devA(timestamp, s2) values 
(%d, %d)", t, t));
+      }
+      for (int t = 4; t <= 5; t++) {
+        statement.execute(
+            String.format("insert into root.db1.devB(timestamp, s1) values 
(%d, %d)", t, t));
+      }
+    }
+
+    List<String> actual =
+        queryTimeseries("show timeseries root.db1.** where time > 3 order by 
timeseries desc");
+    assertEquals(Arrays.asList("root.db1.devB.s1", "root.db1.devA.s1"), 
actual);
+  }
+
+  @Test
+  public void testWhereClauseOffsetAppliedAfterFilter() throws Exception {
+    try (Connection connection = EnvFactory.getEnv().getConnection();
+        Statement statement = connection.createStatement()) {
+      statement.execute("CREATE DATABASE root.ln");
+      statement.execute(
+          "create timeseries root.ln.wf01.wt01.status with datatype=INT32, 
encoding=RLE, compression=SNAPPY");
+      statement.execute(
+          "create timeseries root.ln.wf02.wt01.status with datatype=INT32, 
encoding=RLE, compression=SNAPPY");
+      statement.execute(
+          "create timeseries root.ln.wf02.wt02.status with datatype=INT32, 
encoding=RLE, compression=SNAPPY");
+    }
+
+    List<String> actual =
+        queryTimeseries(
+            "show timeseries root.ln.** where timeseries contains 'wf02.wt' 
order by timeseries offset 1 limit 1");
+    assertEquals(Collections.singletonList("root.ln.wf02.wt02.status"), 
actual);
+  }
+
+  @Test
+  public void testAlterTemplateUpdatesOffsetOrder() throws Exception {
+    try (Connection connection = EnvFactory.getEnv().getConnection();
+        Statement statement = connection.createStatement()) {
+      statement.execute("CREATE DATABASE root.sg1");
+      statement.execute("create device template t1 (s1 INT32, s0 INT32)");
+      statement.execute("set device template t1 to root.sg1.d1");
+      statement.execute("create timeseries using device template on 
root.sg1.d1");
+      statement.execute("set device template t1 to root.sg1.d2");
+      statement.execute("create timeseries using device template on 
root.sg1.d2");
+    }
+
+    List<String> before =
+        queryTimeseries("show timeseries root.sg1.** order by timeseries desc 
offset 2 limit 2");
+    assertEquals(Arrays.asList("root.sg1.d1.s1", "root.sg1.d1.s0"), before);
+
+    try (Connection connection = EnvFactory.getEnv().getConnection();
+        Statement statement = connection.createStatement()) {
+      statement.execute("alter device template t1 add (s00 INT32)");
+    }
+
+    List<String> after =
+        queryTimeseries("show timeseries root.sg1.** order by timeseries 
offset 3 limit 3");
+    assertEquals(Arrays.asList("root.sg1.d2.s0", "root.sg1.d2.s00", 
"root.sg1.d2.s1"), after);
+  }
+}
diff --git 
a/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 
b/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
index efe661e0543..2308d3b81b7 100644
--- 
a/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
+++ 
b/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
@@ -200,7 +200,12 @@ showDevices
 
 // ---- Show Timeseries
 showTimeseries
-    : SHOW LATEST? TIMESERIES prefixPath? timeseriesWhereClause? 
timeConditionClause? rowPaginationClause?
+    : SHOW LATEST? TIMESERIES prefixPath? timeseriesWhereClause? 
timeConditionClause? orderByTimeseriesClause? rowPaginationClause?
+    ;
+
+// order by timeseries for SHOW TIMESERIES
+orderByTimeseriesClause
+    : ORDER BY TIMESERIES (ASC | DESC)?
     ;
 
 // ---- Show Child Paths
@@ -1586,4 +1591,4 @@ subStringExpression
 
 signedIntegerLiteral
     : (PLUS|MINUS)?INTEGER_LITERAL
-    ;
\ No newline at end of file
+    ;
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/thrift/impl/DataNodeInternalRPCServiceImpl.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/thrift/impl/DataNodeInternalRPCServiceImpl.java
index 46d377be0a1..00403b8f9ac 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/thrift/impl/DataNodeInternalRPCServiceImpl.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/thrift/impl/DataNodeInternalRPCServiceImpl.java
@@ -77,6 +77,7 @@ import 
org.apache.iotdb.commons.schema.filter.SchemaFilterFactory;
 import org.apache.iotdb.commons.schema.table.TsTable;
 import org.apache.iotdb.commons.schema.table.TsTableInternalRPCType;
 import org.apache.iotdb.commons.schema.table.TsTableInternalRPCUtil;
+import org.apache.iotdb.commons.schema.template.Template;
 import org.apache.iotdb.commons.schema.view.ViewType;
 import org.apache.iotdb.commons.schema.view.viewExpression.ViewExpression;
 import org.apache.iotdb.commons.service.metric.MetricService;
@@ -186,6 +187,7 @@ import 
org.apache.iotdb.db.schemaengine.schemaregion.read.resp.reader.ISchemaRea
 import org.apache.iotdb.db.schemaengine.table.DataNodeTableCache;
 import org.apache.iotdb.db.schemaengine.template.ClusterTemplateManager;
 import org.apache.iotdb.db.schemaengine.template.TemplateInternalRPCUpdateType;
+import org.apache.iotdb.db.schemaengine.template.TemplateInternalRPCUtil;
 import org.apache.iotdb.db.service.DataNode;
 import org.apache.iotdb.db.service.RegionMigrateService;
 import 
org.apache.iotdb.db.service.externalservice.ExternalServiceManagementService;
@@ -2571,7 +2573,19 @@ public class DataNodeInternalRPCServiceImpl implements 
IDataNodeRPCService.Iface
         
ClusterTemplateManager.getInstance().commitTemplatePreSetInfo(req.getTemplateInfo());
         break;
       case UPDATE_TEMPLATE_INFO:
-        
ClusterTemplateManager.getInstance().updateTemplateInfo(req.getTemplateInfo());
+        Template newTemplate =
+            TemplateInternalRPCUtil.parseUpdateTemplateInfoBytes(
+                ByteBuffer.wrap(req.getTemplateInfo()));
+        Template oldTemplate =
+            
ClusterTemplateManager.getInstance().getTemplate(newTemplate.getId());
+        ClusterTemplateManager.getInstance().updateTemplateInfo(newTemplate);
+        long delta =
+            newTemplate.getMeasurementNumber()
+                - (oldTemplate == null ? 0 : 
oldTemplate.getMeasurementNumber());
+        if (delta != 0) {
+          SchemaEngine.getInstance()
+              .updateSubtreeMeasurementCountForTemplate(newTemplate.getId(), 
delta);
+        }
         break;
       default:
         LOGGER.warn("Unsupported type {} when updating template", req.type);
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/schema/source/LogicalViewSchemaSource.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/schema/source/LogicalViewSchemaSource.java
index f1eaaebbd1d..144ec16d4a3 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/schema/source/LogicalViewSchemaSource.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/schema/source/LogicalViewSchemaSource.java
@@ -79,7 +79,8 @@ public class LogicalViewSchemaSource implements 
ISchemaSource<ITimeSeriesSchemaI
               SchemaFilterFactory.and(
                   schemaFilter, 
SchemaFilterFactory.createViewTypeFilter(ViewType.VIEW)),
               true,
-              scope));
+              scope,
+              null));
     } catch (MetadataException e) {
       throw new SchemaExecutionException(e.getMessage(), e);
     }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/schema/source/SchemaSourceFactory.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/schema/source/SchemaSourceFactory.java
index 2ef0ab9e18a..87560ad47be 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/schema/source/SchemaSourceFactory.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/schema/source/SchemaSourceFactory.java
@@ -26,6 +26,7 @@ import org.apache.iotdb.commons.schema.filter.SchemaFilter;
 import org.apache.iotdb.commons.schema.table.TsTable;
 import org.apache.iotdb.commons.schema.table.column.TsTableColumnSchema;
 import org.apache.iotdb.commons.schema.template.Template;
+import org.apache.iotdb.db.queryengine.plan.statement.component.Ordering;
 import 
org.apache.iotdb.db.schemaengine.schemaregion.read.resp.info.IDeviceSchemaInfo;
 import 
org.apache.iotdb.db.schemaengine.schemaregion.read.resp.info.INodeSchemaInfo;
 import 
org.apache.iotdb.db.schemaengine.schemaregion.read.resp.info.ITimeSeriesSchemaInfo;
@@ -47,7 +48,7 @@ public class SchemaSourceFactory {
       Map<Integer, Template> templateMap,
       PathPatternTree scope) {
     return new TimeSeriesSchemaSource(
-        pathPattern, isPrefixMatch, 0, 0, schemaFilter, templateMap, false, 
scope);
+        pathPattern, isPrefixMatch, 0, 0, schemaFilter, templateMap, false, 
scope, null);
   }
 
   // show time series
@@ -58,9 +59,18 @@ public class SchemaSourceFactory {
       long offset,
       SchemaFilter schemaFilter,
       Map<Integer, Template> templateMap,
-      PathPatternTree scope) {
+      PathPatternTree scope,
+      Ordering timeseriesOrdering) {
     return new TimeSeriesSchemaSource(
-        pathPattern, isPrefixMatch, limit, offset, schemaFilter, templateMap, 
true, scope);
+        pathPattern,
+        isPrefixMatch,
+        limit,
+        offset,
+        schemaFilter,
+        templateMap,
+        true,
+        scope,
+        timeseriesOrdering);
   }
 
   // count device
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/schema/source/TimeSeriesSchemaSource.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/schema/source/TimeSeriesSchemaSource.java
index 40799c548ee..a56cfa228bf 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/schema/source/TimeSeriesSchemaSource.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/schema/source/TimeSeriesSchemaSource.java
@@ -29,6 +29,7 @@ import 
org.apache.iotdb.commons.schema.column.ColumnHeaderConstant;
 import org.apache.iotdb.commons.schema.filter.SchemaFilter;
 import org.apache.iotdb.commons.schema.template.Template;
 import org.apache.iotdb.commons.schema.view.ViewType;
+import org.apache.iotdb.db.queryengine.plan.statement.component.Ordering;
 import org.apache.iotdb.db.schemaengine.schemaregion.ISchemaRegion;
 import 
org.apache.iotdb.db.schemaengine.schemaregion.read.req.SchemaRegionReadPlanFactory;
 import 
org.apache.iotdb.db.schemaengine.schemaregion.read.resp.info.ITimeSeriesSchemaInfo;
@@ -54,6 +55,7 @@ public class TimeSeriesSchemaSource implements 
ISchemaSource<ITimeSeriesSchemaIn
   private final SchemaFilter schemaFilter;
   private final Map<Integer, Template> templateMap;
   private final boolean needViewDetail;
+  private final Ordering timeseriesOrdering;
 
   TimeSeriesSchemaSource(
       PartialPath pathPattern,
@@ -63,7 +65,8 @@ public class TimeSeriesSchemaSource implements 
ISchemaSource<ITimeSeriesSchemaIn
       SchemaFilter schemaFilter,
       Map<Integer, Template> templateMap,
       boolean needViewDetail,
-      PathPatternTree scope) {
+      PathPatternTree scope,
+      Ordering timeseriesOrdering) {
     this.pathPattern = pathPattern;
     this.isPrefixMatch = isPrefixMatch;
     this.limit = limit;
@@ -72,6 +75,7 @@ public class TimeSeriesSchemaSource implements 
ISchemaSource<ITimeSeriesSchemaIn
     this.templateMap = templateMap;
     this.needViewDetail = needViewDetail;
     this.scope = scope;
+    this.timeseriesOrdering = timeseriesOrdering;
   }
 
   @Override
@@ -86,7 +90,8 @@ public class TimeSeriesSchemaSource implements 
ISchemaSource<ITimeSeriesSchemaIn
               isPrefixMatch,
               schemaFilter,
               needViewDetail,
-              scope));
+              scope,
+              timeseriesOrdering));
     } catch (MetadataException e) {
       throw new SchemaExecutionException(e.getMessage(), e);
     }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java
index 70325257b08..e71a1adaaff 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java
@@ -789,6 +789,16 @@ public class ASTVisitor extends 
IoTDBSqlParserBaseVisitor<Statement> {
       showTimeSeriesStatement.setTimeCondition(
           parseWhereClause(ctx.timeConditionClause().whereClause()));
     }
+
+    // ORDER BY TIMESERIES [ASC|DESC]
+    if (ctx.orderByTimeseriesClause() != null) {
+      if (orderByHeat) {
+        throw new SemanticException(
+            "LATEST and ORDER BY TIMESERIES cannot be used at the same time.");
+      }
+      showTimeSeriesStatement.setTimeseriesOrdering(
+          ctx.orderByTimeseriesClause().DESC() != null ? Ordering.DESC : 
Ordering.ASC);
+    }
     if (ctx.rowPaginationClause() != null) {
       if (ctx.rowPaginationClause().limitClause() != null) {
         
showTimeSeriesStatement.setLimit(parseLimitClause(ctx.rowPaginationClause().limitClause()));
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanBuilder.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanBuilder.java
index cc194c36aa7..98f856aff83 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanBuilder.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanBuilder.java
@@ -937,7 +937,7 @@ public class LogicalPlanBuilder {
   }
 
   public LogicalPlanBuilder planLimit(long rowLimit) {
-    if (rowLimit == 0) {
+    if (rowLimit <= 0) {
       return this;
     }
 
@@ -1027,7 +1027,8 @@ public class LogicalPlanBuilder {
       boolean orderByHeat,
       boolean prefixPath,
       Map<Integer, Template> templateMap,
-      PathPatternTree scope) {
+      PathPatternTree scope,
+      Ordering timeseriesOrdering) {
     this.root =
         new TimeSeriesSchemaScanNode(
             context.getQueryId().genPlanNodeId(),
@@ -1038,7 +1039,8 @@ public class LogicalPlanBuilder {
             orderByHeat,
             prefixPath,
             templateMap,
-            scope);
+            scope,
+            timeseriesOrdering);
     return this;
   }
 
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanVisitor.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanVisitor.java
index 8a73227dfad..c3ac21641d1 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanVisitor.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanVisitor.java
@@ -18,6 +18,7 @@
  */
 package org.apache.iotdb.db.queryengine.plan.planner;
 
+import org.apache.iotdb.commons.conf.CommonDescriptor;
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.commons.schema.column.ColumnHeaderConstant;
 import org.apache.iotdb.commons.schema.template.Template;
@@ -54,6 +55,8 @@ import 
org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.InsertTablet
 import 
org.apache.iotdb.db.queryengine.plan.planner.plan.parameter.AggregationStep;
 import org.apache.iotdb.db.queryengine.plan.statement.StatementNode;
 import org.apache.iotdb.db.queryengine.plan.statement.StatementVisitor;
+import org.apache.iotdb.db.queryengine.plan.statement.component.Ordering;
+import org.apache.iotdb.db.queryengine.plan.statement.component.SortItem;
 import org.apache.iotdb.db.queryengine.plan.statement.crud.DeleteDataStatement;
 import 
org.apache.iotdb.db.queryengine.plan.statement.crud.InsertMultiTabletsStatement;
 import org.apache.iotdb.db.queryengine.plan.statement.crud.InsertRowStatement;
@@ -88,6 +91,7 @@ import 
org.apache.iotdb.db.queryengine.plan.statement.metadata.view.ShowLogicalV
 import 
org.apache.iotdb.db.queryengine.plan.statement.pipe.PipeEnrichedStatement;
 import 
org.apache.iotdb.db.queryengine.plan.statement.sys.ExplainAnalyzeStatement;
 import org.apache.iotdb.db.queryengine.plan.statement.sys.ShowQueriesStatement;
+import org.apache.iotdb.db.schemaengine.SchemaEngineMode;
 
 import org.apache.tsfile.enums.TSDataType;
 import org.apache.tsfile.file.metadata.IDeviceID;
@@ -95,6 +99,7 @@ import org.apache.tsfile.utils.Pair;
 import org.apache.tsfile.write.schema.MeasurementSchema;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -557,34 +562,52 @@ public class LogicalPlanVisitor extends 
StatementVisitor<PlanNode, MPPQueryConte
       ShowTimeSeriesStatement showTimeSeriesStatement, MPPQueryContext 
context) {
     LogicalPlanBuilder planBuilder = new LogicalPlanBuilder(analysis, context);
 
+    // Ensure TypeProvider has schema query column types for later SortNode
+    ColumnHeaderConstant.showTimeSeriesColumnHeaders.forEach(
+        columnHeader ->
+            context
+                .getTypeProvider()
+                .setTreeModelType(columnHeader.getColumnName(), 
columnHeader.getColumnType()));
+
     long limit = showTimeSeriesStatement.getLimit();
     long offset = showTimeSeriesStatement.getOffset();
+    Ordering timeseriesOrdering = 
showTimeSeriesStatement.getTimeseriesOrdering();
+    boolean orderByTimeseries = timeseriesOrdering != null;
+    boolean orderByTimeseriesDesc = timeseriesOrdering == Ordering.DESC;
     if (showTimeSeriesStatement.hasTimeCondition()) {
       planBuilder =
-          planBuilder
-              
.planTimeseriesRegionScan(analysis.getDeviceToTimeseriesSchemas(), false)
-              .planLimit(limit)
-              .planOffset(offset);
+          
planBuilder.planTimeseriesRegionScan(analysis.getDeviceToTimeseriesSchemas(), 
false);
+      if (orderByTimeseries) {
+        SortItem sortItem = new SortItem(ColumnHeaderConstant.TIMESERIES, 
timeseriesOrdering);
+        planBuilder = 
planBuilder.planOrderBy(Collections.singletonList(sortItem));
+      }
+      planBuilder = planBuilder.planOffset(offset).planLimit(limit);
       return planBuilder.getRoot();
     }
 
     // If there is only one region, we can push down the offset and limit 
operation to
     // source operator.
-    boolean canPushDownOffsetLimit =
+    boolean singleSchemaRegion =
         analysis.getSchemaPartitionInfo() != null
-            && analysis.getSchemaPartitionInfo().getDistributionInfo().size() 
== 1
-            && !showTimeSeriesStatement.isOrderByHeat();
+            && analysis.getSchemaPartitionInfo().getDistributionInfo().size() 
== 1;
+    boolean isMemorySchemaEngine =
+        CommonDescriptor.getInstance()
+            .getConfig()
+            .getSchemaEngineMode()
+            .equals(SchemaEngineMode.Memory.toString());
+    boolean canPushDownOffsetLimit = false;
 
-    if (showTimeSeriesStatement.isOrderByHeat()) {
+    if (showTimeSeriesStatement.isOrderByHeat()
+        || (!isMemorySchemaEngine && orderByTimeseriesDesc)) {
       limit = 0;
       offset = 0;
-    } else if (!canPushDownOffsetLimit) {
-      limit =
-          showTimeSeriesStatement.getLimit() != 0
-              ? showTimeSeriesStatement.getLimit() + 
showTimeSeriesStatement.getOffset()
-              : 0;
+    } else if (!singleSchemaRegion) {
+      limit = showTimeSeriesStatement.getLimitWithOffset();
       offset = 0;
+    } else {
+      canPushDownOffsetLimit = true;
     }
+
     planBuilder =
         planBuilder
             .planTimeSeriesSchemaSource(
@@ -595,9 +618,17 @@ public class LogicalPlanVisitor extends 
StatementVisitor<PlanNode, MPPQueryConte
                 showTimeSeriesStatement.isOrderByHeat(),
                 showTimeSeriesStatement.isPrefixPath(),
                 analysis.getRelatedTemplateInfo(),
-                showTimeSeriesStatement.getAuthorityScope())
+                showTimeSeriesStatement.getAuthorityScope(),
+                timeseriesOrdering)
             .planSchemaQueryMerge(showTimeSeriesStatement.isOrderByHeat());
 
+    // order by timeseries name in multi-region or PBTree-Desc case: still 
need global SortNode
+    if (orderByTimeseries
+        && (!singleSchemaRegion || (!isMemorySchemaEngine && 
orderByTimeseriesDesc))) {
+      SortItem sortItem = new SortItem(ColumnHeaderConstant.TIMESERIES, 
timeseriesOrdering);
+      planBuilder = 
planBuilder.planOrderBy(Collections.singletonList(sortItem));
+    }
+
     // show latest timeseries
     if (showTimeSeriesStatement.isOrderByHeat()
         && null != analysis.getDataPartitionInfo()
@@ -640,10 +671,7 @@ public class LogicalPlanVisitor extends 
StatementVisitor<PlanNode, MPPQueryConte
     long limit = showDevicesStatement.getLimit();
     long offset = showDevicesStatement.getOffset();
     if (!canPushDownOffsetLimit) {
-      limit =
-          showDevicesStatement.getLimit() != 0
-              ? showDevicesStatement.getLimit() + 
showDevicesStatement.getOffset()
-              : 0;
+      limit = showDevicesStatement.getLimitWithOffset();
       offset = 0;
     }
 
@@ -1015,10 +1043,7 @@ public class LogicalPlanVisitor extends 
StatementVisitor<PlanNode, MPPQueryConte
     long limit = showLogicalViewStatement.getLimit();
     long offset = showLogicalViewStatement.getOffset();
     if (!canPushDownOffsetLimit) {
-      limit =
-          showLogicalViewStatement.getLimit() != 0
-              ? showLogicalViewStatement.getLimit() + 
showLogicalViewStatement.getOffset()
-              : 0;
+      limit = showLogicalViewStatement.getLimitWithOffset();
       offset = 0;
     }
     planBuilder =
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/OperatorTreeGenerator.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/OperatorTreeGenerator.java
index d0e0ff37ca2..0219de6502d 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/OperatorTreeGenerator.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/OperatorTreeGenerator.java
@@ -913,7 +913,8 @@ public class OperatorTreeGenerator extends 
PlanVisitor<Operator, LocalExecutionP
             node.getOffset(),
             node.getSchemaFilter(),
             node.getTemplateMap(),
-            node.getScope()));
+            node.getScope(),
+            node.getTimeseriesOrdering()));
   }
 
   @Override
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/distribution/SimpleFragmentParallelPlanner.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/distribution/SimpleFragmentParallelPlanner.java
index 334d1973f53..25f51f88d9e 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/distribution/SimpleFragmentParallelPlanner.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/distribution/SimpleFragmentParallelPlanner.java
@@ -157,7 +157,9 @@ public class SimpleFragmentParallelPlanner extends 
AbstractFragmentParallelPlann
         || analysis.getTreeStatement() instanceof ExplainAnalyzeStatement
         || analysis.getTreeStatement() instanceof ShowQueriesStatement
         || (analysis.getTreeStatement() instanceof ShowTimeSeriesStatement
-            && ((ShowTimeSeriesStatement) 
analysis.getTreeStatement()).isOrderByHeat())) {
+            && (((ShowTimeSeriesStatement) 
analysis.getTreeStatement()).isOrderByHeat()
+                || ((ShowTimeSeriesStatement) analysis.getTreeStatement())
+                    .isOrderByTimeseries()))) {
       
fragmentInstance.getFragment().generateTypeProvider(queryContext.getTypeProvider());
     }
     instanceMap.putIfAbsent(fragment.getId(), fragmentInstance);
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/metadata/read/TimeSeriesSchemaScanNode.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/metadata/read/TimeSeriesSchemaScanNode.java
index 1997a3caefe..c91f01fd3ce 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/metadata/read/TimeSeriesSchemaScanNode.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/metadata/read/TimeSeriesSchemaScanNode.java
@@ -29,6 +29,7 @@ import org.apache.iotdb.commons.schema.template.Template;
 import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNode;
 import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNodeId;
 import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNodeType;
+import org.apache.iotdb.db.queryengine.plan.statement.component.Ordering;
 
 import org.apache.tsfile.utils.ReadWriteIOUtils;
 
@@ -48,6 +49,9 @@ public class TimeSeriesSchemaScanNode extends 
SchemaQueryScanNode {
   // if is true, the result will be sorted according to the inserting 
frequency of the timeseries
   private final boolean orderByHeat;
 
+  // Ordering of timeseries full path in this region, null means no ordering.
+  private final Ordering timeseriesOrdering;
+
   private final SchemaFilter schemaFilter;
 
   private final Map<Integer, Template> templateMap;
@@ -66,6 +70,25 @@ public class TimeSeriesSchemaScanNode extends 
SchemaQueryScanNode {
     this.schemaFilter = schemaFilter;
     this.orderByHeat = orderByHeat;
     this.templateMap = templateMap;
+    this.timeseriesOrdering = null;
+  }
+
+  public TimeSeriesSchemaScanNode(
+      PlanNodeId id,
+      PartialPath partialPath,
+      SchemaFilter schemaFilter,
+      long limit,
+      long offset,
+      boolean orderByHeat,
+      boolean isPrefixPath,
+      @NotNull Map<Integer, Template> templateMap,
+      @NotNull PathPatternTree scope,
+      Ordering timeseriesOrdering) {
+    super(id, partialPath, limit, offset, isPrefixPath, scope);
+    this.schemaFilter = schemaFilter;
+    this.orderByHeat = orderByHeat;
+    this.templateMap = templateMap;
+    this.timeseriesOrdering = timeseriesOrdering;
   }
 
   public SchemaFilter getSchemaFilter() {
@@ -82,6 +105,8 @@ public class TimeSeriesSchemaScanNode extends 
SchemaQueryScanNode {
     ReadWriteIOUtils.write(offset, byteBuffer);
     ReadWriteIOUtils.write(orderByHeat, byteBuffer);
     ReadWriteIOUtils.write(isPrefixPath, byteBuffer);
+    ReadWriteIOUtils.write(timeseriesOrdering != null, byteBuffer);
+    ReadWriteIOUtils.write(timeseriesOrdering == Ordering.DESC, byteBuffer);
 
     ReadWriteIOUtils.write(templateMap.size(), byteBuffer);
     for (Template template : templateMap.values()) {
@@ -99,6 +124,8 @@ public class TimeSeriesSchemaScanNode extends 
SchemaQueryScanNode {
     ReadWriteIOUtils.write(offset, stream);
     ReadWriteIOUtils.write(orderByHeat, stream);
     ReadWriteIOUtils.write(isPrefixPath, stream);
+    ReadWriteIOUtils.write(timeseriesOrdering != null, stream);
+    ReadWriteIOUtils.write(timeseriesOrdering == Ordering.DESC, stream);
 
     ReadWriteIOUtils.write(templateMap.size(), stream);
     for (Template template : templateMap.values()) {
@@ -120,6 +147,12 @@ public class TimeSeriesSchemaScanNode extends 
SchemaQueryScanNode {
     long offset = ReadWriteIOUtils.readLong(byteBuffer);
     boolean oderByHeat = ReadWriteIOUtils.readBool(byteBuffer);
     boolean isPrefixPath = ReadWriteIOUtils.readBool(byteBuffer);
+    boolean orderByTimeseries = ReadWriteIOUtils.readBool(byteBuffer);
+    boolean orderByTimeseriesDesc = ReadWriteIOUtils.readBool(byteBuffer);
+    Ordering timeseriesOrdering = null;
+    if (orderByTimeseries) {
+      timeseriesOrdering = orderByTimeseriesDesc ? Ordering.DESC : 
Ordering.ASC;
+    }
 
     int templateNum = ReadWriteIOUtils.readInt(byteBuffer);
     Map<Integer, Template> templateMap = new HashMap<>();
@@ -141,13 +174,18 @@ public class TimeSeriesSchemaScanNode extends 
SchemaQueryScanNode {
         oderByHeat,
         isPrefixPath,
         templateMap,
-        scope);
+        scope,
+        timeseriesOrdering);
   }
 
   public boolean isOrderByHeat() {
     return orderByHeat;
   }
 
+  public Ordering getTimeseriesOrdering() {
+    return timeseriesOrdering;
+  }
+
   public Map<Integer, Template> getTemplateMap() {
     return templateMap;
   }
@@ -168,7 +206,8 @@ public class TimeSeriesSchemaScanNode extends 
SchemaQueryScanNode {
         orderByHeat,
         isPrefixPath,
         templateMap,
-        scope);
+        scope,
+        timeseriesOrdering);
   }
 
   @Override
@@ -190,12 +229,14 @@ public class TimeSeriesSchemaScanNode extends 
SchemaQueryScanNode {
       return false;
     }
     TimeSeriesSchemaScanNode that = (TimeSeriesSchemaScanNode) o;
-    return orderByHeat == that.orderByHeat && Objects.equals(schemaFilter, 
that.schemaFilter);
+    return orderByHeat == that.orderByHeat
+        && Objects.equals(timeseriesOrdering, that.timeseriesOrdering)
+        && Objects.equals(schemaFilter, that.schemaFilter);
   }
 
   @Override
   public int hashCode() {
-    return Objects.hash(super.hashCode(), schemaFilter, orderByHeat);
+    return Objects.hash(super.hashCode(), schemaFilter, orderByHeat, 
timeseriesOrdering);
   }
 
   @Override
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/process/ActiveRegionScanMergeNode.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/process/ActiveRegionScanMergeNode.java
index 13718e60437..745b847a106 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/process/ActiveRegionScanMergeNode.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/process/ActiveRegionScanMergeNode.java
@@ -70,6 +70,9 @@ public class ActiveRegionScanMergeNode extends 
MultiChildProcessNode {
 
   @Override
   public List<String> getOutputColumnNames() {
+    if (!children.isEmpty()) {
+      return children.get(0).getOutputColumnNames();
+    }
     return outputCount
         ? ColumnHeaderConstant.countDevicesColumnHeaders.stream()
             .map(ColumnHeader::getColumnName)
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/ShowStatement.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/ShowStatement.java
index 971fae6698b..b8397918217 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/ShowStatement.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/ShowStatement.java
@@ -59,6 +59,13 @@ public class ShowStatement extends 
AuthorityInformationStatement {
     this.offset = offset;
   }
 
+  public long getLimitWithOffset() {
+    if (limit <= 0) {
+      return limit;
+    }
+    return limit + offset;
+  }
+
   public boolean isPrefixPath() {
     return isPrefixPath;
   }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/ShowTimeSeriesStatement.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/ShowTimeSeriesStatement.java
index 82a389d6224..40271c9a92b 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/ShowTimeSeriesStatement.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/ShowTimeSeriesStatement.java
@@ -22,6 +22,7 @@ package 
org.apache.iotdb.db.queryengine.plan.statement.metadata;
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.commons.schema.filter.SchemaFilter;
 import org.apache.iotdb.db.queryengine.plan.statement.StatementVisitor;
+import org.apache.iotdb.db.queryengine.plan.statement.component.Ordering;
 import org.apache.iotdb.db.queryengine.plan.statement.component.WhereCondition;
 
 import java.util.Collections;
@@ -42,6 +43,8 @@ public class ShowTimeSeriesStatement extends ShowStatement {
   // if is true, the result will be sorted according to the inserting 
frequency of the time series
   private final boolean orderByHeat;
   private WhereCondition timeCondition;
+  // order by timeseries name
+  private Ordering timeseriesOrdering;
 
   public ShowTimeSeriesStatement(PartialPath pathPattern, boolean orderByHeat) 
{
     super();
@@ -65,6 +68,18 @@ public class ShowTimeSeriesStatement extends ShowStatement {
     return orderByHeat;
   }
 
+  public boolean isOrderByTimeseries() {
+    return timeseriesOrdering != null;
+  }
+
+  public Ordering getTimeseriesOrdering() {
+    return timeseriesOrdering;
+  }
+
+  public void setTimeseriesOrdering(Ordering timeseriesOrdering) {
+    this.timeseriesOrdering = timeseriesOrdering;
+  }
+
   public void setTimeCondition(WhereCondition timeCondition) {
     this.timeCondition = timeCondition;
   }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/SchemaEngine.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/SchemaEngine.java
index 842281daa96..dafcaa0d3b0 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/SchemaEngine.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/SchemaEngine.java
@@ -43,6 +43,7 @@ import 
org.apache.iotdb.db.schemaengine.schemaregion.ISchemaRegion;
 import org.apache.iotdb.db.schemaengine.schemaregion.ISchemaRegionParams;
 import org.apache.iotdb.db.schemaengine.schemaregion.SchemaRegionLoader;
 import org.apache.iotdb.db.schemaengine.schemaregion.SchemaRegionParams;
+import 
org.apache.iotdb.db.schemaengine.schemaregion.impl.SchemaRegionMemoryImpl;
 import org.apache.iotdb.db.schemaengine.table.DataNodeTableCache;
 import org.apache.iotdb.db.schemaengine.template.ClusterTemplateManager;
 import org.apache.iotdb.mpp.rpc.thrift.TDataNodeHeartbeatReq;
@@ -253,6 +254,26 @@ public class SchemaEngine {
     return new ArrayList<>(schemaRegionMap.keySet());
   }
 
+  public void updateSubtreeMeasurementCountForTemplate(final int templateId, 
final long delta) {
+    if (delta == 0) {
+      return;
+    }
+    for (final ISchemaRegion schemaRegion : schemaRegionMap.values()) {
+      if (schemaRegion instanceof SchemaRegionMemoryImpl) {
+        try {
+          ((SchemaRegionMemoryImpl) schemaRegion)
+              .updateSubtreeMeasurementCountForTemplate(templateId, delta);
+        } catch (MetadataException e) {
+          logger.warn(
+              "Failed to update subtree measurement count for template {} in 
schemaRegion {}",
+              templateId,
+              schemaRegion.getSchemaRegionId(),
+              e);
+        }
+      }
+    }
+  }
+
   public synchronized void createSchemaRegion(
       final String storageGroup, final SchemaRegionId schemaRegionId) throws 
MetadataException {
     if (this.schemaRegionMap == null) {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/impl/SchemaRegionMemoryImpl.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/impl/SchemaRegionMemoryImpl.java
index 230ed8330ca..0719835fe7a 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/impl/SchemaRegionMemoryImpl.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/impl/SchemaRegionMemoryImpl.java
@@ -1450,6 +1450,14 @@ public class SchemaRegionMemoryImpl implements 
ISchemaRegion {
     return result;
   }
 
+  public void updateSubtreeMeasurementCountForTemplate(final int templateId, 
final long delta)
+      throws MetadataException {
+    if (delta == 0 || mTree == null) {
+      return;
+    }
+    mTree.updateSubtreeMeasurementCountForTemplate(templateId, delta);
+  }
+
   @Override
   public int fillLastQueryMap(
       final PartialPath pattern,
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/MTreeBelowSGMemoryImpl.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/MTreeBelowSGMemoryImpl.java
index d409e9e7929..ed519030b63 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/MTreeBelowSGMemoryImpl.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/MTreeBelowSGMemoryImpl.java
@@ -25,6 +25,7 @@ import org.apache.iotdb.commons.exception.MetadataException;
 import org.apache.iotdb.commons.path.MeasurementPath;
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.commons.path.PathPatternTree;
+import org.apache.iotdb.commons.path.PathPatternUtil;
 import org.apache.iotdb.commons.schema.SchemaConstant;
 import org.apache.iotdb.commons.schema.node.role.IDeviceMNode;
 import org.apache.iotdb.commons.schema.node.role.IMeasurementMNode;
@@ -48,6 +49,7 @@ import 
org.apache.iotdb.db.queryengine.common.schematree.ClusterSchemaTree;
 import 
org.apache.iotdb.db.queryengine.execution.operator.schema.source.DeviceAttributeUpdater;
 import 
org.apache.iotdb.db.queryengine.execution.operator.schema.source.DeviceBlackListConstructor;
 import 
org.apache.iotdb.db.queryengine.plan.relational.metadata.fetcher.cache.TableId;
+import org.apache.iotdb.db.queryengine.plan.statement.component.Ordering;
 import org.apache.iotdb.db.schemaengine.metric.SchemaRegionMemMetric;
 import org.apache.iotdb.db.schemaengine.rescon.MemSchemaRegionStatistics;
 import 
org.apache.iotdb.db.schemaengine.schemaregion.mtree.impl.mem.mnode.IMemMNode;
@@ -194,6 +196,22 @@ public class MTreeBelowSGMemoryImpl {
     return store.createSnapshot(snapshotDir);
   }
 
+  private void applySubtreeMeasurementDelta(IMemMNode startNode, final long 
delta) {
+    if (delta == 0 || startNode == null) {
+      return;
+    }
+    IMemMNode current = startNode;
+    while (current != null) {
+      current.setSubtreeMeasurementCount(current.getSubtreeMeasurementCount() 
+ delta);
+      current = current.getParent();
+    }
+  }
+
+  private long getTemplateMeasurementCount(final int templateId) {
+    final Template template = 
ClusterTemplateManager.getInstance().getTemplate(templateId);
+    return template == null ? 0L : template.getMeasurementNumber();
+  }
+
   public static MTreeBelowSGMemoryImpl loadFromSnapshot(
       final File snapshotDir,
       final String databaseFullPath,
@@ -205,18 +223,21 @@ public class MTreeBelowSGMemoryImpl {
       final Function<IMeasurementMNode<IMemMNode>, Map<String, String>> 
tagGetter,
       final Function<IMeasurementMNode<IMemMNode>, Map<String, String>> 
attributeGetter)
       throws IOException, IllegalPathException {
-    return new MTreeBelowSGMemoryImpl(
-        PartialPath.getQualifiedDatabasePartialPath(databaseFullPath),
-        MemMTreeStore.loadFromSnapshot(
-            snapshotDir,
-            measurementProcess,
-            deviceProcess,
-            tableDeviceProcess,
-            regionStatistics,
-            metric),
-        tagGetter,
-        attributeGetter,
-        regionStatistics);
+    final MTreeBelowSGMemoryImpl mtree =
+        new MTreeBelowSGMemoryImpl(
+            PartialPath.getQualifiedDatabasePartialPath(databaseFullPath),
+            MemMTreeStore.loadFromSnapshot(
+                snapshotDir,
+                measurementProcess,
+                deviceProcess,
+                tableDeviceProcess,
+                regionStatistics,
+                metric),
+            tagGetter,
+            attributeGetter,
+            regionStatistics);
+    mtree.rebuildSubtreeMeasurementCount();
+    return mtree;
   }
 
   // endregion
@@ -316,6 +337,7 @@ public class MTreeBelowSGMemoryImpl {
         entityMNode.addAlias(alias, measurementMNode);
       }
 
+      applySubtreeMeasurementDelta(measurementMNode.getAsMNode(), 1L);
       return measurementMNode;
     }
   }
@@ -413,6 +435,7 @@ public class MTreeBelowSGMemoryImpl {
         if (aliasList != null && aliasList.get(i) != null) {
           entityMNode.addAlias(aliasList.get(i), measurementMNode);
         }
+        applySubtreeMeasurementDelta(measurementMNode.getAsMNode(), 1L);
         measurementMNodeList.add(measurementMNode);
       }
       return measurementMNodeList;
@@ -621,6 +644,7 @@ public class MTreeBelowSGMemoryImpl {
       if (deletedNode.getAlias() != null) {
         parent.getAsDeviceMNode().deleteAliasChild(deletedNode.getAlias());
       }
+      applySubtreeMeasurementDelta(parent, -1L);
     }
     deleteEmptyInternalMNode(parent.getAsDeviceMNode());
     return deletedNode;
@@ -1027,6 +1051,7 @@ public class MTreeBelowSGMemoryImpl {
     entityMNode.setUseTemplate(true);
     entityMNode.setSchemaTemplateId(template.getId());
     regionStatistics.activateTemplate(template.getId());
+    applySubtreeMeasurementDelta(entityMNode.getAsMNode(), (long) 
template.getMeasurementNumber());
   }
 
   public Map<PartialPath, List<Integer>> constructSchemaBlackListWithTemplate(
@@ -1091,6 +1116,8 @@ public class MTreeBelowSGMemoryImpl {
                 resultTemplateSetInfo.put(
                     node.getPartialPath(), 
Collections.singletonList(node.getSchemaTemplateId()));
                 
regionStatistics.deactivateTemplate(node.getSchemaTemplateId());
+                applySubtreeMeasurementDelta(
+                    node.getAsMNode(), 
-getTemplateMeasurementCount(node.getSchemaTemplateId()));
                 node.deactivateTemplate();
                 deleteEmptyInternalMNode(node);
               }
@@ -1123,6 +1150,35 @@ public class MTreeBelowSGMemoryImpl {
     entityMNode.setUseTemplate(true);
     entityMNode.setSchemaTemplateId(templateId);
     regionStatistics.activateTemplate(templateId);
+    applySubtreeMeasurementDelta(entityMNode.getAsMNode(), 
getTemplateMeasurementCount(templateId));
+  }
+
+  public void updateSubtreeMeasurementCountForTemplate(final int templateId, 
final long delta)
+      throws MetadataException {
+    if (delta == 0) {
+      return;
+    }
+    final PartialPath pattern =
+        new PartialPath(
+            databaseMNode.getFullPath()
+                + IoTDBConstant.PATH_SEPARATOR
+                + IoTDBConstant.MULTI_LEVEL_PATH_WILDCARD);
+    try (final EntityUpdater<IMemMNode> updater =
+        new EntityUpdater<IMemMNode>(
+            rootNode, pattern, store, false, SchemaConstant.ALL_MATCH_SCOPE) {
+          @Override
+          protected void updateEntity(final IDeviceMNode<IMemMNode> node) {
+            if (!node.isUseTemplate() || node.getSchemaTemplateId() != 
templateId) {
+              return;
+            }
+            synchronized (MTreeBelowSGMemoryImpl.this) {
+              applySubtreeMeasurementDelta(node.getAsMNode(), delta);
+            }
+          }
+        }) {
+      updater.setSchemaTemplateFilter(templateId);
+      updater.update();
+    }
   }
 
   public long countPathsUsingTemplate(final PartialPath pathPattern, final int 
templateId)
@@ -1134,6 +1190,23 @@ public class MTreeBelowSGMemoryImpl {
     }
   }
 
+  public void rebuildSubtreeMeasurementCount() {
+    rebuildSubtreeMeasurementCountFromNode(rootNode);
+  }
+
+  private long rebuildSubtreeMeasurementCountFromNode(final IMemMNode node) {
+    long count = node.isMeasurement() ? 1L : 0L;
+    final IMNodeIterator<IMemMNode> iterator = store.getChildrenIterator(node);
+    while (iterator.hasNext()) {
+      count += rebuildSubtreeMeasurementCountFromNode(iterator.next());
+    }
+    if (node.isDevice() && node.getAsDeviceMNode().isUseTemplate()) {
+      count += 
getTemplateMeasurementCount(node.getAsDeviceMNode().getSchemaTemplateId());
+    }
+    node.setSubtreeMeasurementCount(count);
+    return count;
+  }
+
   // endregion
 
   // region Interfaces for schema reader
@@ -1446,6 +1519,76 @@ public class MTreeBelowSGMemoryImpl {
             showTimeSeriesPlan.isPrefixMatch(),
             showTimeSeriesPlan.getScope()) {
 
+          private long remainingOffset =
+              showTimeSeriesPlan.getSchemaFilter() == null ? 
showTimeSeriesPlan.getOffset() : 0;
+          private final String[] prunePrefixNodes =
+              getSafePrunePrefixNodes(showTimeSeriesPlan.getPath());
+
+          private String[] getSafePrunePrefixNodes(final PartialPath pattern) {
+            if (pattern == null || !pattern.endWithMultiLevelWildcard()) {
+              return null;
+            }
+            final String[] nodes = pattern.getNodes();
+            return Arrays.copyOf(nodes, nodes.length - 1);
+          }
+
+          private boolean isUnderPrunePrefix(final IMemMNode node) {
+            if (prunePrefixNodes == null) {
+              return false;
+            }
+            final String[] nodePath = 
getPartialPathFromRootToNode(node).getNodes();
+            if (nodePath.length < prunePrefixNodes.length) {
+              return false;
+            }
+            for (int i = 0; i < prunePrefixNodes.length; i++) {
+              if (!PathPatternUtil.isNodeMatch(prunePrefixNodes[i], 
nodePath[i])) {
+                return false;
+              }
+            }
+            return true;
+          }
+
+          private boolean shouldPruneSubtree(final IMemMNode node) {
+            if (remainingOffset <= 0) {
+              return false;
+            }
+            if (!isUnderPrunePrefix(node)) {
+              return false;
+            }
+            final long subtreeCount = node.getSubtreeMeasurementCount();
+            if (subtreeCount <= remainingOffset) {
+              remainingOffset -= subtreeCount;
+              return true;
+            }
+            return false;
+          }
+
+          @Override
+          protected boolean acceptFullMatchedNode(final IMemMNode node) {
+            if (!node.isMeasurement()) {
+              return false;
+            }
+            if (remainingOffset > 0) {
+              // skip this measurement
+              remainingOffset--;
+              return false;
+            }
+            return true;
+          }
+
+          @Override
+          protected boolean shouldVisitSubtreeOfInternalMatchedNode(final 
IMemMNode node) {
+            if (shouldPruneSubtree(node)) {
+              return false;
+            }
+            return !node.isMeasurement();
+          }
+
+          @Override
+          protected boolean shouldVisitSubtreeOfFullMatchedNode(final 
IMemMNode node) {
+            return !node.isMeasurement() && !shouldPruneSubtree(node);
+          }
+
           @Override
           protected ITimeSeriesSchemaInfo collectMeasurement(
               final IMeasurementMNode<IMemMNode> node) {
@@ -1506,15 +1649,41 @@ public class MTreeBelowSGMemoryImpl {
               }
             };
           }
+
+          @Override
+          protected Iterator<IMemMNode> getChildrenIterator(final IMemMNode 
parent)
+              throws MetadataException {
+            Iterator<IMemMNode> baseIterator = 
super.getChildrenIterator(parent);
+
+            Ordering timeseriesOrdering = 
showTimeSeriesPlan.getTimeseriesOrdering();
+            if (timeseriesOrdering == null) {
+              return baseIterator;
+            }
+
+            List<IMemMNode> children = new ArrayList<>();
+            while (baseIterator.hasNext()) {
+              children.add(baseIterator.next());
+            }
+            releaseNodeIterator(baseIterator);
+
+            children.sort(
+                (a, b) -> {
+                  int cmp = a.getName().compareTo(b.getName());
+                  return timeseriesOrdering == Ordering.DESC ? -cmp : cmp;
+                });
+            return children.iterator();
+          }
         };
 
     collector.setTemplateMap(showTimeSeriesPlan.getRelatedTemplate(), 
nodeFactory);
     final ISchemaReader<ITimeSeriesSchemaInfo> reader =
         new TimeseriesReaderWithViewFetch(
             collector, showTimeSeriesPlan.getSchemaFilter(), 
showTimeSeriesPlan.needViewDetail());
-    if (showTimeSeriesPlan.getLimit() > 0 || showTimeSeriesPlan.getOffset() > 
0) {
+    final long offsetForWrapper =
+        showTimeSeriesPlan.getSchemaFilter() == null ? 0 : 
showTimeSeriesPlan.getOffset();
+    if (showTimeSeriesPlan.getLimit() > 0 || offsetForWrapper > 0) {
       return new SchemaReaderLimitOffsetWrapper<>(
-          reader, showTimeSeriesPlan.getLimit(), 
showTimeSeriesPlan.getOffset());
+          reader, showTimeSeriesPlan.getLimit(), offsetForWrapper);
     } else {
       return reader;
     }
@@ -1626,6 +1795,7 @@ public class MTreeBelowSGMemoryImpl {
       measurementMNode.setParent(entityMNode.getAsMNode());
       store.addChild(entityMNode.getAsMNode(), leafName, 
measurementMNode.getAsMNode());
 
+      applySubtreeMeasurementDelta(measurementMNode.getAsMNode(), 1L);
       return measurementMNode;
     }
   }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/mnode/IMemMNode.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/mnode/IMemMNode.java
index d3d055928b1..6cd14800f3e 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/mnode/IMemMNode.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/mnode/IMemMNode.java
@@ -20,4 +20,13 @@ package 
org.apache.iotdb.db.schemaengine.schemaregion.mtree.impl.mem.mnode;
 
 import org.apache.iotdb.commons.schema.node.IMNode;
 
-public interface IMemMNode extends IMNode<IMemMNode> {}
+public interface IMemMNode extends IMNode<IMemMNode> {
+
+  /**
+   * The count of measurement nodes contained in the subtree rooted at this 
node. The counter is
+   * maintained in memory only.
+   */
+  long getSubtreeMeasurementCount();
+
+  void setSubtreeMeasurementCount(long subtreeMeasurementCount);
+}
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/mnode/basic/BasicMNode.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/mnode/basic/BasicMNode.java
index a033c56c67e..2eab69749fd 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/mnode/basic/BasicMNode.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/mnode/basic/BasicMNode.java
@@ -46,6 +46,9 @@ public class BasicMNode implements IMemMNode {
   private IMemMNode parent;
   private final BasicMNodeInfo basicMNodeInfo;
 
+  /** Cached count of measurements in this node's subtree, rebuilt on restart. 
*/
+  private long subtreeMeasurementCount = 0L;
+
   /** from root to this node, only be set when used once for InternalMNode */
   private String fullPath;
 
@@ -99,6 +102,16 @@ public class BasicMNode implements IMemMNode {
     this.fullPath = fullPath;
   }
 
+  @Override
+  public long getSubtreeMeasurementCount() {
+    return subtreeMeasurementCount;
+  }
+
+  @Override
+  public void setSubtreeMeasurementCount(final long subtreeMeasurementCount) {
+    this.subtreeMeasurementCount = subtreeMeasurementCount;
+  }
+
   @Override
   public PartialPath getPartialPath() {
     final List<String> detachedPath = new ArrayList<>();
@@ -225,6 +238,7 @@ public class BasicMNode implements IMemMNode {
    *         <li>basicMNodeInfo reference, 8B
    *         <li>parent reference, 8B
    *         <li>fullPath reference, 8B
+   *         <li>subtreeMeasurementCount, 8B
    *       </ol>
    *   <li>MapEntry in parent
    *       <ol>
@@ -236,7 +250,7 @@ public class BasicMNode implements IMemMNode {
    */
   @Override
   public int estimateSize() {
-    return 8 + 8 + 8 + 8 + 8 + 8 + 28 + basicMNodeInfo.estimateSize();
+    return 8 + 8 + 8 + 8 + 8 + 8 + 8 + 28 + basicMNodeInfo.estimateSize();
   }
 
   @Override
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/mnode/impl/AboveDatabaseMNode.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/mnode/impl/AboveDatabaseMNode.java
index cff30d8b8c4..87144d4954a 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/mnode/impl/AboveDatabaseMNode.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/mnode/impl/AboveDatabaseMNode.java
@@ -33,4 +33,14 @@ public class AboveDatabaseMNode extends 
AbstractAboveDatabaseMNode<IMemMNode, Ba
   public IMemMNode getAsMNode() {
     return this;
   }
+
+  @Override
+  public long getSubtreeMeasurementCount() {
+    return basicMNode.getSubtreeMeasurementCount();
+  }
+
+  @Override
+  public void setSubtreeMeasurementCount(long subtreeMeasurementCount) {
+    basicMNode.setSubtreeMeasurementCount(subtreeMeasurementCount);
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/mnode/impl/DatabaseMNode.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/mnode/impl/DatabaseMNode.java
index c6b2f5e2427..290cf427360 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/mnode/impl/DatabaseMNode.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/mnode/impl/DatabaseMNode.java
@@ -45,4 +45,14 @@ public class DatabaseMNode extends 
AbstractDatabaseMNode<IMemMNode, BasicInterna
   public void setDeviceInfo(IDeviceInfo<IMemMNode> deviceInfo) {
     basicMNode.setDeviceInfo(deviceInfo);
   }
+
+  @Override
+  public long getSubtreeMeasurementCount() {
+    return basicMNode.getSubtreeMeasurementCount();
+  }
+
+  @Override
+  public void setSubtreeMeasurementCount(long subtreeMeasurementCount) {
+    basicMNode.setSubtreeMeasurementCount(subtreeMeasurementCount);
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/mnode/impl/MeasurementMNode.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/mnode/impl/MeasurementMNode.java
index a40cbe6bc0f..d2a2cbd80c9 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/mnode/impl/MeasurementMNode.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/mnode/impl/MeasurementMNode.java
@@ -52,4 +52,14 @@ public class MeasurementMNode extends 
AbstractMeasurementMNode<IMemMNode, BasicM
   public final boolean isLogicalView() {
     return false;
   }
+
+  @Override
+  public long getSubtreeMeasurementCount() {
+    return basicMNode.getSubtreeMeasurementCount();
+  }
+
+  @Override
+  public void setSubtreeMeasurementCount(long subtreeMeasurementCount) {
+    basicMNode.setSubtreeMeasurementCount(subtreeMeasurementCount);
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/pbtree/MTreeBelowSGCachedImpl.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/pbtree/MTreeBelowSGCachedImpl.java
index 8952f9d6cfc..8ca06b83f7d 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/pbtree/MTreeBelowSGCachedImpl.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/pbtree/MTreeBelowSGCachedImpl.java
@@ -42,6 +42,7 @@ import 
org.apache.iotdb.db.exception.metadata.PathNotExistException;
 import 
org.apache.iotdb.db.exception.metadata.template.DifferentTemplateException;
 import 
org.apache.iotdb.db.exception.metadata.template.TemplateIsInUseException;
 import org.apache.iotdb.db.queryengine.common.schematree.ClusterSchemaTree;
+import org.apache.iotdb.db.queryengine.plan.statement.component.Ordering;
 import org.apache.iotdb.db.schemaengine.metric.SchemaRegionCachedMetric;
 import org.apache.iotdb.db.schemaengine.rescon.CachedSchemaRegionStatistics;
 import 
org.apache.iotdb.db.schemaengine.schemaregion.mtree.impl.pbtree.mnode.ICachedMNode;
@@ -64,6 +65,7 @@ import 
org.apache.iotdb.db.schemaengine.schemaregion.read.resp.info.impl.Timeser
 import 
org.apache.iotdb.db.schemaengine.schemaregion.read.resp.reader.ISchemaReader;
 import 
org.apache.iotdb.db.schemaengine.schemaregion.read.resp.reader.impl.SchemaReaderLimitOffsetWrapper;
 import 
org.apache.iotdb.db.schemaengine.schemaregion.read.resp.reader.impl.TimeseriesReaderWithViewFetch;
+import org.apache.iotdb.db.schemaengine.schemaregion.utils.MNodeUtils;
 import org.apache.iotdb.db.schemaengine.schemaregion.utils.MetaFormatUtils;
 import 
org.apache.iotdb.db.schemaengine.schemaregion.utils.filter.DeviceFilterVisitor;
 import org.apache.iotdb.db.schemaengine.template.ClusterTemplateManager;
@@ -83,8 +85,10 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -1506,6 +1510,150 @@ public class MTreeBelowSGCachedImpl {
               }
             };
           }
+
+          @Override
+          protected Iterator<ICachedMNode> getChildrenIterator(final 
ICachedMNode parent)
+              throws MetadataException {
+            Ordering timeseriesOrdering = 
showTimeSeriesPlan.getTimeseriesOrdering();
+            if (timeseriesOrdering == null || timeseriesOrdering == 
Ordering.DESC) {
+              return super.getChildrenIterator(parent);
+            }
+
+            final Iterator<ICachedMNode> templateIterator = 
getSortedTemplateChildren(parent);
+            if (!templateIterator.hasNext()) {
+              return super.getChildrenIterator(parent);
+            }
+
+            return new IMNodeIterator<ICachedMNode>() {
+              private ICachedMNode next = null;
+              private ICachedMNode nextDirect = null;
+              private ICachedMNode nextTemplate = null;
+              private boolean skipTemplateChildren = false;
+              // Lazy init: avoid prefetching direct iterator before template 
collection/sort.
+              private IMNodeIterator<ICachedMNode> directIterator = null;
+
+              @Override
+              public boolean hasNext() {
+                if (next != null) {
+                  return true;
+                }
+                next = computeNext();
+                return next != null;
+              }
+
+              @Override
+              public ICachedMNode next() {
+                if (!hasNext()) {
+                  throw new NoSuchElementException();
+                }
+                ICachedMNode result = next;
+                next = null;
+                return result;
+              }
+
+              @Override
+              public void skipTemplateChildren() {
+                skipTemplateChildren = true;
+                nextTemplate = null;
+              }
+
+              @Override
+              public void close() {
+                if (directIterator != null) {
+                  directIterator.close();
+                }
+              }
+
+              private ICachedMNode computeNext() {
+                if (nextDirect == null) {
+                  nextDirect = fetchNextDirect();
+                }
+                if (nextTemplate == null && !skipTemplateChildren) {
+                  nextTemplate = fetchNextTemplate();
+                }
+
+                if (nextDirect == null && (skipTemplateChildren || 
nextTemplate == null)) {
+                  return null;
+                }
+                if (nextDirect == null) {
+                  ICachedMNode result = nextTemplate;
+                  nextTemplate = null;
+                  return result;
+                }
+                if (skipTemplateChildren || nextTemplate == null) {
+                  ICachedMNode result = nextDirect;
+                  nextDirect = null;
+                  return result;
+                }
+
+                int cmp = 
nextDirect.getName().compareTo(nextTemplate.getName());
+                if (cmp <= 0) {
+                  ICachedMNode result = nextDirect;
+                  nextDirect = null;
+                  return result;
+                } else {
+                  ICachedMNode result = nextTemplate;
+                  nextTemplate = null;
+                  return result;
+                }
+              }
+
+              private ICachedMNode fetchNextDirect() {
+                if (directIterator == null) {
+                  try {
+                    directIterator = store.getChildrenIterator(parent);
+                  } catch (MetadataException e) {
+                    throw new RuntimeException(e);
+                  }
+                }
+                while (directIterator.hasNext()) {
+                  ICachedMNode node = directIterator.next();
+                  if (!skipPreDeletedSchema
+                      || !node.isMeasurement()
+                      || !node.getAsMeasurementMNode().isPreDeleted()) {
+                    return node;
+                  }
+                }
+                return null;
+              }
+
+              private ICachedMNode fetchNextTemplate() {
+                while (templateIterator.hasNext()) {
+                  ICachedMNode node = templateIterator.next();
+                  if (!skipPreDeletedSchema
+                      || !node.isMeasurement()
+                      || !node.getAsMeasurementMNode().isPreDeleted()) {
+                    return node;
+                  }
+                }
+                return null;
+              }
+            };
+          }
+
+          private Iterator<ICachedMNode> getSortedTemplateChildren(final 
ICachedMNode parent) {
+            if (templateMap == null || templateMap.isEmpty() || 
!parent.isDevice()) {
+              return Collections.emptyIterator();
+            }
+            final IDeviceMNode<ICachedMNode> deviceNode = 
parent.getAsDeviceMNode();
+            if (deviceNode.getSchemaTemplateId() == 
SchemaConstant.NON_TEMPLATE) {
+              return Collections.emptyIterator();
+            }
+            if (skipPreDeletedSchema && 
deviceNode.isPreDeactivateSelfOrTemplate()) {
+              return Collections.emptyIterator();
+            }
+            final Template template = 
templateMap.get(deviceNode.getSchemaTemplateId());
+            if (template == null) {
+              return Collections.emptyIterator();
+            }
+            final List<ICachedMNode> children = new ArrayList<>();
+            final Iterator<ICachedMNode> iterator = 
MNodeUtils.getChildren(template, nodeFactory);
+            while (iterator.hasNext()) {
+              children.add(iterator.next());
+            }
+            children.sort(Comparator.comparing(ICachedMNode::getName));
+            return children.iterator();
+          }
         };
 
     collector.setTemplateMap(showTimeSeriesPlan.getRelatedTemplate(), 
nodeFactory);
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/read/req/IShowTimeSeriesPlan.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/read/req/IShowTimeSeriesPlan.java
index e05ee54f253..81612e2f7c7 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/read/req/IShowTimeSeriesPlan.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/read/req/IShowTimeSeriesPlan.java
@@ -22,6 +22,7 @@ package 
org.apache.iotdb.db.schemaengine.schemaregion.read.req;
 
 import org.apache.iotdb.commons.schema.filter.SchemaFilter;
 import org.apache.iotdb.commons.schema.template.Template;
+import org.apache.iotdb.db.queryengine.plan.statement.component.Ordering;
 
 import java.util.Map;
 
@@ -32,4 +33,7 @@ public interface IShowTimeSeriesPlan extends IShowSchemaPlan {
   SchemaFilter getSchemaFilter();
 
   Map<Integer, Template> getRelatedTemplate();
+
+  /** Ordering of timeseries full path in this region, null means no ordering. 
*/
+  Ordering getTimeseriesOrdering();
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/read/req/SchemaRegionReadPlanFactory.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/read/req/SchemaRegionReadPlanFactory.java
index 84a2ca9cdf7..4fe59c58e7a 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/read/req/SchemaRegionReadPlanFactory.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/read/req/SchemaRegionReadPlanFactory.java
@@ -23,6 +23,7 @@ import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.commons.path.PathPatternTree;
 import org.apache.iotdb.commons.schema.filter.SchemaFilter;
 import org.apache.iotdb.commons.schema.template.Template;
+import org.apache.iotdb.db.queryengine.plan.statement.component.Ordering;
 import 
org.apache.iotdb.db.schemaengine.schemaregion.read.req.impl.ShowDevicesPlanImpl;
 import 
org.apache.iotdb.db.schemaengine.schemaregion.read.req.impl.ShowNodesPlanImpl;
 import 
org.apache.iotdb.db.schemaengine.schemaregion.read.req.impl.ShowTimeSeriesPlanImpl;
@@ -61,9 +62,18 @@ public class SchemaRegionReadPlanFactory {
       boolean isPrefixMatch,
       SchemaFilter schemaFilter,
       boolean needViewDetail,
-      PathPatternTree scope) {
+      PathPatternTree scope,
+      Ordering timeseriesOrdering) {
     return new ShowTimeSeriesPlanImpl(
-        path, relatedTemplate, limit, offset, isPrefixMatch, schemaFilter, 
needViewDetail, scope);
+        path,
+        relatedTemplate,
+        limit,
+        offset,
+        isPrefixMatch,
+        schemaFilter,
+        needViewDetail,
+        scope,
+        timeseriesOrdering);
   }
 
   public static IShowNodesPlan getShowNodesPlan(PartialPath path, 
PathPatternTree scope) {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/read/req/impl/ShowTimeSeriesPlanImpl.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/read/req/impl/ShowTimeSeriesPlanImpl.java
index 8aeb0e837be..7bb5aa9d91c 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/read/req/impl/ShowTimeSeriesPlanImpl.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/read/req/impl/ShowTimeSeriesPlanImpl.java
@@ -24,6 +24,7 @@ import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.commons.path.PathPatternTree;
 import org.apache.iotdb.commons.schema.filter.SchemaFilter;
 import org.apache.iotdb.commons.schema.template.Template;
+import org.apache.iotdb.db.queryengine.plan.statement.component.Ordering;
 import 
org.apache.iotdb.db.schemaengine.schemaregion.read.req.IShowTimeSeriesPlan;
 
 import java.util.Map;
@@ -37,6 +38,9 @@ public class ShowTimeSeriesPlanImpl extends 
AbstractShowSchemaPlanImpl
   private final SchemaFilter schemaFilter;
   private final boolean needViewDetail;
 
+  // order-by-timeseries pushdown ordering inside a single SchemaRegion
+  private final Ordering timeseriesOrdering;
+
   public ShowTimeSeriesPlanImpl(
       PartialPath path,
       Map<Integer, Template> relatedTemplate,
@@ -45,11 +49,13 @@ public class ShowTimeSeriesPlanImpl extends 
AbstractShowSchemaPlanImpl
       boolean isPrefixMatch,
       SchemaFilter schemaFilter,
       boolean needViewDetail,
-      PathPatternTree scope) {
+      PathPatternTree scope,
+      Ordering timeseriesOrdering) {
     super(path, limit, offset, isPrefixMatch, scope);
     this.relatedTemplate = relatedTemplate;
     this.schemaFilter = schemaFilter;
     this.needViewDetail = needViewDetail;
+    this.timeseriesOrdering = timeseriesOrdering;
   }
 
   @Override
@@ -67,18 +73,24 @@ public class ShowTimeSeriesPlanImpl extends 
AbstractShowSchemaPlanImpl
     return relatedTemplate;
   }
 
+  @Override
+  public Ordering getTimeseriesOrdering() {
+    return timeseriesOrdering;
+  }
+
   @Override
   public boolean equals(Object o) {
     if (this == o) return true;
     if (o == null || getClass() != o.getClass()) return false;
     if (!super.equals(o)) return false;
     ShowTimeSeriesPlanImpl that = (ShowTimeSeriesPlanImpl) o;
-    return Objects.equals(relatedTemplate, that.relatedTemplate)
+    return Objects.equals(timeseriesOrdering, that.timeseriesOrdering)
+        && Objects.equals(relatedTemplate, that.relatedTemplate)
         && Objects.equals(schemaFilter, that.schemaFilter);
   }
 
   @Override
   public int hashCode() {
-    return Objects.hash(super.hashCode(), relatedTemplate, schemaFilter);
+    return Objects.hash(super.hashCode(), relatedTemplate, schemaFilter, 
timeseriesOrdering);
   }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/read/resp/reader/impl/SchemaReaderLimitOffsetWrapper.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/read/resp/reader/impl/SchemaReaderLimitOffsetWrapper.java
index f35d047753f..04f4ca8b6f9 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/read/resp/reader/impl/SchemaReaderLimitOffsetWrapper.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/read/resp/reader/impl/SchemaReaderLimitOffsetWrapper.java
@@ -45,7 +45,7 @@ public class SchemaReaderLimitOffsetWrapper<T extends 
ISchemaInfo> implements IS
     this.schemaReader = schemaReader;
     this.limit = limit;
     this.offset = offset;
-    this.hasLimit = limit > 0 || offset > 0;
+    this.hasLimit = limit > 0;
   }
 
   @Override
@@ -73,24 +73,20 @@ public class SchemaReaderLimitOffsetWrapper<T extends 
ISchemaInfo> implements IS
   }
 
   private ListenableFuture<?> tryGetNext() {
-    if (hasLimit) {
-      if (curOffset < offset) {
-        // first time
-        return Futures.submit(
-            () -> {
-              while (curOffset < offset && schemaReader.hasNext()) {
-                schemaReader.next();
-                curOffset++;
-              }
-              return schemaReader.hasNext();
-            },
-            directExecutor());
-      }
-      if (count >= limit) {
-        return NOT_BLOCKED;
-      } else {
-        return schemaReader.isBlocked();
-      }
+    if (curOffset < offset) {
+      // first time
+      return Futures.submit(
+          () -> {
+            while (curOffset < offset && schemaReader.hasNext()) {
+              schemaReader.next();
+              curOffset++;
+            }
+            return schemaReader.hasNext();
+          },
+          directExecutor());
+    }
+    if (hasLimit && count >= limit) {
+      return NOT_BLOCKED;
     } else {
       return schemaReader.isBlocked();
     }
@@ -101,7 +97,7 @@ public class SchemaReaderLimitOffsetWrapper<T extends 
ISchemaInfo> implements IS
   public boolean hasNext() {
     try {
       isBlocked().get();
-      return schemaReader.hasNext() && (limit == 0 || count < limit);
+      return schemaReader.hasNext() && (!hasLimit || count < limit);
     } catch (Exception e) {
       throw new RuntimeException(e);
     }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/template/ClusterTemplateManager.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/template/ClusterTemplateManager.java
index 857db657077..41fb89efcc5 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/template/ClusterTemplateManager.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/template/ClusterTemplateManager.java
@@ -618,10 +618,14 @@ public class ClusterTemplateManager implements 
ITemplateManager {
   }
 
   public void updateTemplateInfo(byte[] templateInfo) {
+    Template template =
+        
TemplateInternalRPCUtil.parseUpdateTemplateInfoBytes(ByteBuffer.wrap(templateInfo));
+    updateTemplateInfo(template);
+  }
+
+  public void updateTemplateInfo(Template template) {
     readWriteLock.writeLock().lock();
     try {
-      Template template =
-          
TemplateInternalRPCUtil.parseUpdateTemplateInfoBytes(ByteBuffer.wrap(templateInfo));
       templateIdMap.put(template.getId(), template);
     } finally {
       readWriteLock.writeLock().unlock();
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/metadata/schemaRegion/SchemaRegionTestUtil.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/metadata/schemaRegion/SchemaRegionTestUtil.java
index 42800c4e586..8a24133d453 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/metadata/schemaRegion/SchemaRegionTestUtil.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/metadata/schemaRegion/SchemaRegionTestUtil.java
@@ -175,7 +175,15 @@ public class SchemaRegionTestUtil {
     try (ISchemaReader<ITimeSeriesSchemaInfo> timeSeriesReader =
         schemaRegion.getTimeSeriesReader(
             SchemaRegionReadPlanFactory.getShowTimeSeriesPlan(
-                pathPattern, templateMap, 0, 0, isPrefixMatch, null, false, 
ALL_MATCH_SCOPE))) {
+                pathPattern,
+                templateMap,
+                0,
+                0,
+                isPrefixMatch,
+                null,
+                false,
+                ALL_MATCH_SCOPE,
+                null))) {
       long count = 0;
       while (timeSeriesReader.hasNext()) {
         timeSeriesReader.next();
@@ -200,7 +208,15 @@ public class SchemaRegionTestUtil {
     try (final ISchemaReader<ITimeSeriesSchemaInfo> timeSeriesReader =
         schemaRegion.getTimeSeriesReader(
             SchemaRegionReadPlanFactory.getShowTimeSeriesPlan(
-                pathPattern, Collections.emptyMap(), 0, 0, false, null, false, 
ALL_MATCH_SCOPE))) {
+                pathPattern,
+                Collections.emptyMap(),
+                0,
+                0,
+                false,
+                null,
+                false,
+                ALL_MATCH_SCOPE,
+                null))) {
       Assert.assertTrue(timeSeriesReader.hasNext());
       final ITimeSeriesSchemaInfo info = timeSeriesReader.next();
       Assert.assertEquals(isAligned, info.isUnderAlignedDevice());
@@ -237,7 +253,7 @@ public class SchemaRegionTestUtil {
     try (ISchemaReader<ITimeSeriesSchemaInfo> timeSeriesReader =
         schemaRegion.getTimeSeriesReader(
             SchemaRegionReadPlanFactory.getShowTimeSeriesPlan(
-                pathPattern, null, 0, 0, isPrefixMatch, null, false, 
ALL_MATCH_SCOPE))) {
+                pathPattern, null, 0, 0, isPrefixMatch, null, false, 
ALL_MATCH_SCOPE, null))) {
       Map<PartialPath, Long> countMap = new HashMap<>();
       while (timeSeriesReader.hasNext()) {
         ITimeSeriesSchemaInfo timeSeriesSchemaInfo = timeSeriesReader.next();
@@ -356,7 +372,8 @@ public class SchemaRegionTestUtil {
                 isPrefixMatch,
                 schemaFilter,
                 needViewDetail,
-                ALL_MATCH_SCOPE))) {
+                ALL_MATCH_SCOPE,
+                null))) {
       while (reader.hasNext()) {
         timeSeriesSchemaInfo = reader.next();
         result.add(
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/operator/schema/SchemaQueryScanOperatorTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/operator/schema/SchemaQueryScanOperatorTest.java
index a5d4a6e6ace..75d450430ad 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/operator/schema/SchemaQueryScanOperatorTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/operator/schema/SchemaQueryScanOperatorTest.java
@@ -215,7 +215,8 @@ public class SchemaQueryScanOperatorTest {
               0,
               null,
               Collections.emptyMap(),
-              SchemaConstant.ALL_MATCH_SCOPE);
+              SchemaConstant.ALL_MATCH_SCOPE,
+              null);
       SchemaOperatorTestUtil.mockGetSchemaReader(
           timeSeriesSchemaSource, showTimeSeriesResults.iterator(), 
schemaRegion, true);
 


Reply via email to