Skip to content

Conversation

@xiangmy21
Copy link
Contributor

feat: show timeseries [order by timseries] clause

Support ORDER BY TIMESERIES in SHOW TIMESERIES and Optimize OFFSET with Subtree Measurement Statistics


Brief

This PR introduces ordering support for SHOW TIMESERIES by measurement name (lexicographical) and optimizes the performance of the OFFSET clause using subtree measurement statistics.

Currently, SHOW TIMESERIES supports the ORDER BY TIMESERIES clause.
When the query scope is within a single database, OFFSET X no longer requires traversing the first X measurements one by one. Instead, it skips subtrees in the metadata tree based on subtree measurement counts.

Example:

IoTDB> show timeseries root.dbtest.** order by timeseries desc limit 5 offset 5001
+--------------------------------+-----+-----------+--------+--------+-----------+----+----------+--------+------------------+--------+
|                      Timeseries|Alias|   Database|DataType|Encoding|Compression|Tags|Attributes|Deadband|DeadbandParameters|ViewType|
+--------------------------------+-----+-----------+--------+--------+-----------+----+----------+--------+------------------+--------+
|root.dbtest.plant9.device84.m188| null|root.dbtest|   INT32|     RLE|     SNAPPY|null|      null|    null|              null|    BASE|
|root.dbtest.plant9.device84.m187| null|root.dbtest|   INT32|     RLE|     SNAPPY|null|      null|    null|              null|    BASE|
|root.dbtest.plant9.device84.m186| null|root.dbtest|   INT32|     RLE|     SNAPPY|null|      null|    null|              null|    BASE|
|root.dbtest.plant9.device84.m185| null|root.dbtest|   INT32|     RLE|     SNAPPY|null|      null|    null|              null|    BASE|
|root.dbtest.plant9.device84.m184| null|root.dbtest|   INT32|     RLE|     SNAPPY|null|      null|    null|              null|    BASE|
+--------------------------------+-----+-----------+--------+--------+-----------+----+----------+--------+------------------+--------+
  • DESC: descending order
  • ASC: ascending order (default if not specified)

Design & Implementation Details

1. Syntax Extension

  • Updated the grammar of SHOW TIMESERIES to support orderByTimeseriesClause.
  • Added ordering-related fields to ShowTimeSeriesStatement to record sorting requirements.

2. Logical Plan Construction

  • Introduced a SortNode at the top of the logical plan to enable global ordering across partitions.
  • For single-partition queries, LIMIT and OFFSET are pushed down to the metadata tree traversal stage in LogicalPlanVisitor.

3. Limit/Offset Handling in Multi-Partition Queries

  • For multi-partition queries, OFFSET cannot be pushed down.
    Instead, limit' = limit + offset is used.
  • Fixed a bug in the previous implementation:
    when limit = 0 (which is treated as unlimited in IoTDB), limit' was incorrectly pushed down, causing unexpected truncation of results.

4. Ordered Traversal in Metadata Tree

  • In MTreeBelowSGMemoryImpl, the iteration strategy of child nodes in schemaReader is overridden under ordering mode.
  • Child nodes are traversed in lexicographical order by name.

5. Subtree Measurement Count

  • Implemented subtree measurement statistics (only for in-memory metadata tree):

    • Added subtreeMeasurementCount to IMemMNode and related classes.
    • Maintained subtreeMeasurementCount along ancestor paths during measurement insertion and deletion.
    • This value is not persisted; it is initialized via a DFS during metadata tree loading.
  • During schemaReader construction, acceptFullMatchedNode is overridden to skip subtree traversal when subtreeMeasurementCount < offset.


Tests

Functional Tests

  • Added IoTDBShowTimeseriesOrderByTimeseriesIT to verify correctness of ordering and offset behavior.

Performance Evaluation

  • Evaluated performance on a single-partition dataset with a typical three-level hierarchy:
    root.plantA.deviceB.measurementC
    
    with approximately 900,000 measurements.
  • Query pattern:
    SHOW TIMESERIES root.dbtest.** order by timeseries LIMIT 100 OFFSET X;
    where X ranges from 0 to 900,000 with a step of 5,000.
  • Compared the original implementation and the optimized version.
  • Results are shown in the figure below:
image
  • Detailed benchmark methodology and results are available at: [link].

Impact

  • Enables deterministic ordering for SHOW TIMESERIES.
  • Significantly reduces traversal cost for large OFFSET values in single-partition scenarios $O(limit+offset)\to O(limit+TreeHeight)$.
  • Improves correctness of limit/offset handling in multi-partition queries.
  • Introduces minimal overhead to metadata maintenance (in-memory only).

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds ORDER BY TIMESERIES [ASC|DESC] support to SHOW TIMESERIES and introduces an in-memory metadata-tree optimization to speed up large OFFSET values by pruning whole subtrees using cached subtree measurement counts.

Changes:

  • Extends SQL grammar + statement model to represent ORDER BY TIMESERIES (ASC/DESC).
  • Updates planning/execution to support ordering (global sort in multi-region; ordered traversal pushdown in single region) and optimizes OFFSET using subtree measurement statistics.
  • Adds/updates schema-region read plan plumbing and introduces an integration test for ordering behavior.

Reviewed changes

Copilot reviewed 24 out of 24 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 Adds orderByTimeseriesClause to SHOW TIMESERIES grammar.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java Parses ORDER BY TIMESERIES and enforces semantic constraints.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/ShowTimeSeriesStatement.java Stores order-by-timeseries flags and ordering direction.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/ShowStatement.java Adds getLimitWithOffset() helper for multi-region limit/offset handling.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanVisitor.java Wires ordering and limit/offset handling into logical plan; adds global SortNode when needed.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LogicalPlanBuilder.java Extends schema source planning to pass ordering flags; adjusts limit handling.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/metadata/read/TimeSeriesSchemaScanNode.java Persists order-by-timeseries flags through plan-node serialization.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/OperatorTreeGenerator.java Passes ordering flags down into schema source creation.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/distribution/SimpleFragmentParallelPlanner.java Ensures type provider generation for order-by-timeseries scenarios.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/schema/source/SchemaSourceFactory.java Threads ordering flags into TimeSeriesSchemaSource creation.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/schema/source/TimeSeriesSchemaSource.java Threads ordering flags into schema-region read plans.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/schema/source/LogicalViewSchemaSource.java Updates show-timeseries plan invocation signature.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/read/req/IShowTimeSeriesPlan.java Adds region-level order-by-timeseries flags.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/read/req/SchemaRegionReadPlanFactory.java Extends plan factory API for ordering flags.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/read/req/impl/ShowTimeSeriesPlanImpl.java Implements the new ordering-flag accessors and equality updates.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/mnode/IMemMNode.java Adds subtree measurement count getters/setters to mem-nodes.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/mnode/basic/BasicMNode.java Adds cached subtreeMeasurementCount field and size estimation adjustment.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/mnode/impl/{AboveDatabaseMNode,DatabaseMNode,MeasurementMNode}.java Delegates subtree measurement count storage to BasicMNode.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/MTreeBelowSGMemoryImpl.java Maintains subtree counts, rebuilds on snapshot load, prunes traversal for OFFSET, and sorts children for ordered traversal.
iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/operator/schema/SchemaQueryScanOperatorTest.java Updates test wiring for new plan parameters.
iotdb-core/datanode/src/test/java/org/apache/iotdb/db/metadata/schemaRegion/SchemaRegionTestUtil.java Updates test plan factory calls with new params.
integration-test/src/test/java/org/apache/iotdb/db/it/schema/IoTDBShowTimeseriesOrderByTimeseriesIT.java Adds IT coverage for ordering + offset/limit and conflict semantics.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant