Query Performance Analysis

1. Overview

Query analysis helps users understand the execution mechanism and performance bottlenecks of queries, enabling query optimization and performance tuning. The IoTDB table model provides two types of query analysis statements:

  • EXPLAIN: Previews the execution plan of a query SQL, showing how IoTDB organizes data retrieval and processing.

  • EXPLAIN ANALYZE: Actually executes the query on top of EXPLAIN, and displays the time, resource consumption, and operator statistics during query execution.

The default output of EXPLAIN and EXPLAIN ANALYZE is designed for human reading and is suitable for direct viewing in the CLI. For scenarios that require stable parsing of query plans or execution statistics, such as Web Console, CI regression testing, and automated performance diagnosis systems, you can use the JSON output format to obtain structured results. The JSON format is supported since V2.0.11.

1.1 Comparison of Query Analysis Methods

Compared with Arthas sampling and other troubleshooting methods, EXPLAIN ANALYZE requires no additional components and can perform distributed tracing on a single SQL, making it more suitable for locating performance issues of specific queries.

MethodInstallation DifficultyBusiness ImpactFunctional Scope
EXPLAIN ANALYZE statementLow. No additional components required, built-in IoTDB SQL statementLow. Only affects the single query being analyzed, no impact on other online workloadsSupports distributed, can trace a single SQL
Arthas samplingMedium. Requires installing the Java Arthas toolHigh. CPU sampling may affect online business response speedDoes not support distributed, only supports analysis of overall query load and time consumption of the database

2. EXPLAIN

2.1 Syntax

The EXPLAIN command is used to view the distributed execution plan of a SQL query. The execution plan is displayed as an operator tree, describing how IoTDB will execute the query.

EXPLAIN [(FORMAT { GRAPHVIZ | JSON })] <SELECT_STATEMENT>

Where:

ParameterDescription
SELECT_STATEMENTThe query statement to be analyzed
FORMAT GRAPHVIZOutputs the distributed plan in the default graphical text form, suitable for human reading
FORMAT JSONOutputs the distributed plan as a JSON object, suitable for programmatic parsing (supported since V2.0.11)

The format name after FORMAT is case-insensitive, for example, FORMAT json is equivalent to FORMAT JSON.

2.2 Default GRAPHVIZ Format

The default format of EXPLAIN is GRAPHVIZ. After execution, you will get the distribution plan result column.

Taking table1 in the sample data as an example, the following two statements are equivalent:

EXPLAIN SELECT * FROM table1;
EXPLAIN (FORMAT GRAPHVIZ) SELECT * FROM table1;

After executing the above statements, the output is as follows: IoTDB reads data from different data partitions through DeviceTableScanNode nodes, and aggregates and returns the results through the Collect operator.

+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|                                                                                                                                                                                                                                distribution plan|
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|                                                            ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐                                                             |
|                                                            │OutputNode-4                                                                                                          │                                                             |
|                                                            │OutputColumns-[time, region, plant_id, device_id, model_id, maintenance, temperature, humidity, status, arrival_time] │                                                             |
|                                                            │OutputSymbols: [time, region, plant_id, device_id, model_id, maintenance, temperature, humidity, status, arrival_time]│                                                             |
|                                                            └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘                                                             |
|                                                                                                                        │                                                                                                                        |
|                                                                                                                        │                                                                                                                        |
|                                                            ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐                                                             |
|                                                            │Collect-33                                                                                                            │                                                             |
|                                                            │OutputSymbols: [time, region, plant_id, device_id, model_id, maintenance, temperature, humidity, status, arrival_time]│                                                             |
|                                                            └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘                                                             |
|                                                            ┌───────────────────────────────────────────────────────────┴────────────────────────────────────────────────────────────┐                                                           |
|                                                            │                                                                                                                        │                                                           |
|                                                     ┌───────────┐                                                                                                            ┌───────────┐                                                      |
|                                                     │Exchange-40│                                                                                                            │Exchange-41│                                                      |
|                                                     └───────────┘                                                                                                            └───────────┘                                                      |
|                                                            │                                                                                                                        │                                                           |
|                                                            │                                                                                                                        │                                                           |
|┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐|
|│DeviceTableScanNode-32                                                                                                │ │DeviceTableScanNode-31                                                                                                │|
|│QualifiedTableName: database1.table1                                                                                  │ │QualifiedTableName: database1.table1                                                                                  │|
|│OutputSymbols: [time, region, plant_id, device_id, model_id, maintenance, temperature, humidity, status, arrival_time]│ │OutputSymbols: [time, region, plant_id, device_id, model_id, maintenance, temperature, humidity, status, arrival_time]│|
|│DeviceNumber: 4                                                                                                       │ │DeviceNumber: 2                                                                                                       │|
|│ScanOrder: ASC                                                                                                        │ │ScanOrder: ASC                                                                                                        │|
|│PushDownOffset: 0                                                                                                     │ │PushDownOffset: 0                                                                                                     │|
|│PushDownLimit: 0                                                                                                      │ │PushDownLimit: 0                                                                                                      │|
|│PushDownLimitToEachDevice: false                                                                                      │ │PushDownLimitToEachDevice: false                                                                                      │|
|│RegionId: 1                                                                                                           │ │RegionId: 2                                                                                                           │|
|└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘|
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

2.3 JSON Format

Using EXPLAIN (FORMAT JSON) returns the JSON representation of the distributed plan tree. The result set is a single-column output, and in JSON format returns a single row with a single JSON object, making it convenient for JDBC clients or automation tools to read directly.

The top-level structure of EXPLAIN (FORMAT JSON) varies with the query type:

ScenarioTop-level StructureDescription
Regular queryplan node JSON objectThe top-level is directly a plan node object such as OutputNode
Query containing materialized CTEwrapper JSON objectThe top-level contains cteQueries and mainQuery, used to retain both the CTE subquery plan and the main query plan

Each plan node is output as a JSON object. The basic fields are as follows:

FieldType/OccurrenceDescription
namestringThe display name formed by concatenating the node type and plan node id, for example OutputNode-4
idstringplan node id
propertiesobjectNode properties. Only output when the node has displayable properties
childrenarrayArray of child nodes. Only output when the node has child nodes

Common plan node properties include:

Node TypeMain Fields/Properties
OutputNodeOutputColumns, OutputSymbols
TableScanNode / DeviceTableScanNodeQualifiedTableName, OutputSymbols, DeviceNumber, ScanOrder, TimePredicate, PushDownPredicate, PushDownOffset, PushDownLimit, PushDownLimitToEachDevice, RegionId
TreeDeviceViewScanNodeIn addition to table scan properties, adds TreeDB, MeasurementToColumnName
AggregationNodeOutputSymbols, Aggregators, GroupingKeys, Streamable, PreGroupedSymbols, Step
FilterNodePredicate
ProjectNodeOutputSymbols, Expressions
LimitNode / OffsetNodeCount
SortNode / MergeSortNodeOrderBy
JoinNodeJoinType, Criteria, OutputSymbols
UnionNodeOutputSymbols
ExplainAnalyzeNodeChildPermittedOutputs

When the query contains a materialized CTE, the JSON top-level is no longer a single plan node directly, but is wrapped as:

{
  "cteQueries": [
    {
      "name": "cte1",
      "plan": {
        "name": "OutputNode-<id>",
        "id": "<id>"
      }
    }
  ],
  "mainQuery": {
    "name": "OutputNode-<id>",
    "id": "<id>"
  }
}

Where cteQueries[].plan and mainQuery are both plan node JSON objects. This structure is used to retain both the CTE subquery plan and the main query plan.

Taking table1 in the sample data as an example:

EXPLAIN (FORMAT JSON) SELECT * FROM table1;
+-----------------+
|distribution plan|
+-----------------+
{
  "name": "OutputNode-4",
  "id": "4",
  "properties": {
    "OutputColumns": [
      "time",
      "region",
      "plant_id",
      "device_id",
      "model_id",
      "maintenance",
      "temperature",
      "humidity",
      "status",
      "arrival_time"
    ],
    "OutputSymbols": [
      "time",
      "region",
      "plant_id",
      "device_id",
      "model_id",
      "maintenance",
      "temperature",
      "humidity",
      "status",
      "arrival_time"
    ]
  },
  "children": [
    {
      "name": "CollectNode-33",
      "id": "33",
      "children": [
        {
          "name": "ExchangeNode-40",
          "id": "40",
          "children": [
            {
              "name": "DeviceTableScanNode-32",
              "id": "32",
              "properties": {
                "QualifiedTableName": "database1.table1",
                "OutputSymbols": [
                  "time",
                  "region",
                  "plant_id",
                  "device_id",
                  "model_id",
                  "maintenance",
                  "temperature",
                  "humidity",
                  "status",
                  "arrival_time"
                ],
                "DeviceNumber": "4",
                "ScanOrder": "ASC",
                "PushDownOffset": "0",
                "PushDownLimit": "0",
                "PushDownLimitToEachDevice": "false",
                "RegionId": "1"
              }
            }
          ]
        },
        {
          "name": "ExchangeNode-41",
          "id": "41",
          "children": [
            {
              "name": "DeviceTableScanNode-31",
              "id": "31",
              "properties": {
                "QualifiedTableName": "database1.table1",
                "OutputSymbols": [
                  "time",
                  "region",
                  "plant_id",
                  "device_id",
                  "model_id",
                  "maintenance",
                  "temperature",
                  "humidity",
                  "status",
                  "arrival_time"
                ],
                "DeviceNumber": "2",
                "ScanOrder": "ASC",
                "PushDownOffset": "0",
                "PushDownLimit": "0",
                "PushDownLimitToEachDevice": "false",
                "RegionId": "2"
              }
            }
          ]
        }
      ]
    }
  ]
}
+-----------------+

3. EXPLAIN ANALYZE

3.1 Syntax

EXPLAIN ANALYZE is a performance analysis SQL built into the IoTDB query engine. Unlike EXPLAIN, it actually executes the corresponding query plan and collects execution information, which can be used to track the specific performance distribution of a query, assisting in resource observation, performance tuning, and exception analysis.

EXPLAIN ANALYZE [VERBOSE] [(FORMAT { TEXT | JSON })] <SELECT_STATEMENT>

Where:

ParameterDescription
SELECT_STATEMENTThe query statement to be analyzed
VERBOSEPrints more detailed analysis results. When not specified, some fine-grained statistics are omitted
FORMAT TEXTOutputs analysis results in the default text form, suitable for human reading
FORMAT JSONOutputs analysis results as a JSON object, suitable for programmatic parsing (supported since V2.0.11)

3.2 Default TEXT Format

The default format of EXPLAIN ANALYZE is TEXT. After execution, you will get the Explain Analyze result column. The results consist of query planning statistics, fragment instance statistics, data reading statistics, and operator tree statistics.

  • Query Planning Statistics

QueryStatistics contains query-level statistics:

FieldType/OccurrenceDescription
Analyze CostQuery planning statisticsTime consumed in the SQL analysis phase
Fetch Partition CostQuery planning statisticsTime consumed fetching the partition table
Fetch Schema CostQuery planning statisticsTime consumed fetching metadata and permission validation
Logical Plan CostQuery planning statisticsTime consumed building the logical plan
Logical Optimization CostQuery planning statisticsTime consumed in logical plan optimization
Distribution Plan CostQuery planning statisticsTime consumed building the distributed plan
Dispatch CostQuery planning statisticsTime consumed dispatching fragment instances
Fragment Instances CountQuery planning statisticsTotal number of query fragments; each fragment's information is output in sequence
  • Fragment Instance Statistics

FragmentInstance is the encapsulation of an IoTDB query fragment. Each query fragment outputs a copy of execution information, mainly including fragment statistics and operator information.

Fragment statistics include:

FieldType/OccurrenceDescription
Total Wall TimeFragment statisticsPhysical time from when the fragment starts execution to when it finishes
Cost of initDataQuerySourceFragment statisticsTime consumed building the query file list
Seq File(unclosed)Fragment statisticsNumber of unclosed sequential files
Seq File(closed)Fragment statisticsNumber of closed sequential files
UnSeq File(unclosed)Fragment statisticsNumber of unclosed out-of-order files
UnSeq File(closed)Fragment statisticsNumber of closed out-of-order files
ready queued timeFragment statisticsTotal time all tasks of the query fragment spent in the ready queue
blocked queued timeFragment statisticsTotal time all tasks of the query fragment spent in the blocked queue
  • Data Reading Statistics

Query Statistics detail fields include:

FieldType/OccurrenceDescription
loadBloomFilterFromCacheCountBloomFilterNumber of BloomFilterCache hits
loadBloomFilterFromDiskCountBloomFilterNumber of times BloomFilter was read from disk
loadBloomFilterActualIOSizeBloomFilterDisk IO generated when reading BloomFilter from disk, in bytes
loadBloomFilterTimeBloomFilterTotal time spent reading BloomFilter and computing whether a series exists, in ms
loadTimeSeriesMetadataDiskSeqCountTimeSeriesMetadataNumber of TimeSeriesMetadata loaded from closed sequential files
loadTimeSeriesMetadataDiskUnSeqCountTimeSeriesMetadataNumber of TimeSeriesMetadata loaded from closed out-of-order files
loadTimeSeriesMetadataDiskSeqTimeTimeSeriesMetadataTime consumed loading TimeSeriesMetadata from closed sequential files
loadTimeSeriesMetadataDiskUnSeqTimeTimeSeriesMetadataTime consumed loading TimeSeriesMetadata from closed out-of-order files
loadTimeSeriesMetadataFromCacheCountTimeSeriesMetadataNumber of TimeSeriesMetadataCache hits
loadTimeSeriesMetadataFromDiskCountTimeSeriesMetadataNumber of times TimeSeriesMetadata was read from disk
loadTimeSeriesMetadataActualIOSizeTimeSeriesMetadataDisk IO generated when reading TimeSeriesMetadata from disk, in bytes
TimeSeriesMetadataModificationTimeMods fileTime consumed reading mods files
constructAlignedChunkReadersDiskCountChunkNumber of times ChunkReader was constructed
constructAlignedChunkReadersDiskTimeChunkTotal time consumed constructing ChunkReader, including disk IO and decompression
pageReadersDecodeAlignedDiskCountChunkNumber of pages decoded
pageReadersDecodeAlignedDiskTimeChunkTotal time consumed decoding pages
loadChunkFromCacheCountChunkNumber of ChunkCache hits
loadChunkFromDiskCountChunkNumber of times Chunk was read from disk
loadChunkActualIOSizeChunkDisk IO generated when reading Chunk from disk, in bytes
  • Operator Tree Statistics

Operator tree statistics include:

FieldType/OccurrenceDescription
CPU TimeOperator tree statisticsCPU execution time of the current operator
outputOperator tree statisticsNumber of output rows of the current operator
HasNext() Called CountOperator tree statisticsNumber of times the current operator's HasNext() interface was called
Next() Called CountOperator tree statisticsNumber of times the current operator's Next() interface was called
Estimated Memory SizeOperator tree statisticsEstimated memory usage of the current operator
Node-specific statisticsOperator tree statisticsCustom statistics fields output by different operators, such as DeviceNumber, CurrentDeviceIndex, OutputPlanNodeId, size_in_bytes, etc.

Common node-specific statistics fields include:

FieldType/OccurrenceDescription
DeviceNumberTableScan related nodesNumber of devices involved in the current table scan
CurrentDeviceIndexTableScan related nodesIndex of the device currently being scanned
OutputPlanNodeIdsink nodeThe downstream data-receiving node corresponding to the sink node
size_in_bytesexchange nodeNumber of bytes of TsBlock received by the exchange node, only counting data size
TimeSeriesIndexFilteredRowstable scan node when filter is pushed down to table scanNumber of data rows filtered out by series metadata
ChunkIndexFilteredRowstable scan node when filter is pushed down to table scanNumber of data rows filtered out by chunk metadata
PageIndexFilteredRowstable scan node when filter is pushed down to table scanNumber of data rows filtered out by page header internal statistics
RowScanFilteredRowstable scan node when filter is pushed down to table scan and VERBOSE is usedNumber of rows filtered out during row-by-row data checking

The actual output fields vary with the query type, the operators involved, whether VERBOSE is used, and whether filter pushdown is triggered. When the corresponding logic is not triggered, the relevant fields may not appear in the result.

  • Text Output Example

Taking table1 in the sample data as an example, the following two statements are equivalent:

EXPLAIN ANALYZE SELECT * FROM table1;
EXPLAIN ANALYZE (FORMAT TEXT) SELECT * FROM table1;
+-------------------------------------------------------------------------------------------------------------------------+
|                                                                                                          Explain Analyze|
+-------------------------------------------------------------------------------------------------------------------------+
|Analyze Cost: 3.862 ms                                                                                                   |
|Fetch Partition Cost: 0.785 ms                                                                                           |
|Fetch Schema Cost: 5.473 ms                                                                                              |
|Logical Plan Cost: 37.350 ms                                                                                             |
|Logical Optimization Cost: 4.340 ms                                                                                      |
|Distribution Plan Cost: 1.287 ms                                                                                         |
|Dispatch Cost: 8.711 ms                                                                                                  |
|Fragment Instances Count: 3                                                                                              |
|                                                                                                                         |
|FRAGMENT-INSTANCE[Id: 20260722_064147_00096_1.2.0][IP: 127.0.0.1:10730][DataRegion: virtual_data_region][State: FINISHED]|
|  Total Wall Time: 64 ms                                                                                                 |
|  Cost of initDataQuerySource: 0.000 ms                                                                                  |
|  Seq File(unclosed): 0, Seq File(closed): 0                                                                             |
|  UnSeq File(unclosed): 0, UnSeq File(closed): 0                                                                         |
|  ready queued time: 0.428 ms, blocked queued time: 11.410 ms                                                            |
|  Query Statistics:                                                                                                      |
|    timeSeriesIndexFilteredRows: 0                                                                                       |
|    chunkIndexFilteredRows: 0                                                                                            |
|    pageIndexFilteredRows: 0                                                                                             |
|    [PlanNodeId 69]: IdentitySinkNode(IdentitySinkOperator)                                                              |
|        CPU Time: 28.691 ms                                                                                              |
|        output: 18 rows                                                                                                  |
|        HasNext() Called Count: 9                                                                                        |
|        Next() Called Count: 8                                                                                           |
|        Estimated Memory Size: 131072                                                                                    |
|        DownStreamPlanNodeId: 66                                                                                         |
|      [PlanNodeId 55]: CollectNode(CollectOperator)                                                                      |
|          CPU Time: 28.656 ms                                                                                            |
|          output: 18 rows                                                                                                |
|          HasNext() Called Count: 9                                                                                      |
|          Next() Called Count: 8                                                                                         |
|          Estimated Memory Size: 131072                                                                                  |
|        [PlanNodeId 64]: ExchangeNode(ExchangeOperator)                                                                  |
|            CPU Time: 13.310 ms                                                                                          |
|            output: 12 rows                                                                                              |
|            HasNext() Called Count: 5                                                                                    |
|            Next() Called Count: 4                                                                                       |
|            Estimated Memory Size: 131072                                                                                |
|            size_in_bytes: 3264                                                                                          |
|        [PlanNodeId 65]: ExchangeNode(ExchangeOperator)                                                                  |
|            CPU Time: 15.286 ms                                                                                          |
|            output: 6 rows                                                                                               |
|            HasNext() Called Count: 3                                                                                    |
|            Next() Called Count: 2                                                                                       |
|            Estimated Memory Size: 131072                                                                                |
|            size_in_bytes: 1632                                                                                          |
|                                                                                                                         |
|FRAGMENT-INSTANCE[Id: 20260722_064147_00096_1.3.0][IP: 127.0.0.1:10730][DataRegion: 1][State: FINISHED]                  |
|  Total Wall Time: 32 ms                                                                                                 |
|  Cost of initDataQuerySource: 7.652 ms                                                                                  |
|  Seq File(unclosed): 0, Seq File(closed): 0                                                                             |
|  UnSeq File(unclosed): 2, UnSeq File(closed): 0                                                                         |
|  ready queued time: 0.089 ms, blocked queued time: 0.000 ms                                                             |
|  Query Statistics:                                                                                                      |
|    timeSeriesIndexFilteredRows: 0                                                                                       |
|    chunkIndexFilteredRows: 0                                                                                            |
|    pageIndexFilteredRows: 0                                                                                             |
|    [PlanNodeId 67]: IdentitySinkNode(IdentitySinkOperator)                                                              |
|        CPU Time: 2.007 ms                                                                                               |
|        output: 12 rows                                                                                                  |
|        HasNext() Called Count: 9                                                                                        |
|        Next() Called Count: 8                                                                                           |
|        Estimated Memory Size: 327680                                                                                    |
|        DownStreamPlanNodeId: 64                                                                                         |
|      [PlanNodeId 54]: DeviceTableScanNode(TableScanOperator)                                                            |
|          CPU Time: 1.981 ms                                                                                             |
|          output: 12 rows                                                                                                |
|          HasNext() Called Count: 9                                                                                      |
|          Next() Called Count: 8                                                                                         |
|          Estimated Memory Size: 327680                                                                                  |
|          DeviceNumber: 4                                                                                                |
|          CurrentDeviceIndex: 3                                                                                          |
|                                                                                                                         |
|FRAGMENT-INSTANCE[Id: 20260722_064147_00096_1.4.0][IP: 127.0.0.1:10730][DataRegion: 2][State: FINISHED]                  |
|  Total Wall Time: 48 ms                                                                                                 |
|  Cost of initDataQuerySource: 0.933 ms                                                                                  |
|  Seq File(unclosed): 0, Seq File(closed): 0                                                                             |
|  UnSeq File(unclosed): 1, UnSeq File(closed): 0                                                                         |
|  ready queued time: 0.141 ms, blocked queued time: 0.000 ms                                                             |
|  Query Statistics:                                                                                                      |
|    timeSeriesIndexFilteredRows: 0                                                                                       |
|    chunkIndexFilteredRows: 0                                                                                            |
|    pageIndexFilteredRows: 0                                                                                             |
|    [PlanNodeId 68]: IdentitySinkNode(IdentitySinkOperator)                                                              |
|        CPU Time: 1.846 ms                                                                                               |
|        output: 6 rows                                                                                                   |
|        HasNext() Called Count: 5                                                                                        |
|        Next() Called Count: 4                                                                                           |
|        Estimated Memory Size: 327680                                                                                    |
|        DownStreamPlanNodeId: 65                                                                                         |
|      [PlanNodeId 53]: DeviceTableScanNode(TableScanOperator)                                                            |
|          CPU Time: 1.755 ms                                                                                             |
|          output: 6 rows                                                                                                 |
|          HasNext() Called Count: 5                                                                                      |
|          Next() Called Count: 4                                                                                         |
|          Estimated Memory Size: 327680                                                                                  |
|          DeviceNumber: 2                                                                                                |
|          CurrentDeviceIndex: 1                                                                                          |
+-------------------------------------------------------------------------------------------------------------------------+
  • VERBOSE Output Example

Using VERBOSE you can view finer-grained data reading and filtering statistics:

EXPLAIN ANALYZE VERBOSE SELECT * FROM table1;
EXPLAIN ANALYZE VERBOSE (FORMAT TEXT) SELECT * FROM table1;
+-------------------------------------------------------------------------------------------------------------------------+
|                                                                                                          Explain Analyze|
+-------------------------------------------------------------------------------------------------------------------------+
|Analyze Cost: 1.016 ms                                                                                                   |
|Fetch Partition Cost: 0.555 ms                                                                                           |
|Fetch Schema Cost: 3.789 ms                                                                                              |
|Logical Plan Cost: 0.491 ms                                                                                             |
|Logical Optimization Cost: 2.625 ms                                                                                      |
|Distribution Plan Cost: 0.393 ms                                                                                         |
|Dispatch Cost: 37.041 ms                                                                                                 |
|Fragment Instances Count: 3                                                                                              |
|                                                                                                                         |
|FRAGMENT-INSTANCE[Id: 20260722_064913_00105_1.2.0][IP: 127.0.0.1:10730][DataRegion: virtual_data_region][State: FINISHED]|
|  Total Wall Time: 43 ms                                                                                                 |
|  Cost of initDataQuerySource: 0.000 ms                                                                                  |
|  Seq File(unclosed): 0, Seq File(closed): 0                                                                             |
|  UnSeq File(unclosed): 0, UnSeq File(closed): 0                                                                         |
|  ready queued time: 0.248 ms, blocked queued time: 23.757 ms                                                            |
|  Query Statistics:                                                                                                      |
|    loadBloomFilterFromCacheCount: 0                                                                                     |
|    loadBloomFilterFromDiskCount: 0                                                                                     |
|    loadBloomFilterActualIOSize: 0                                                                                       |
|    loadBloomFilterTime: 0.000                                                                                           |
|    loadTimeSeriesMetadataFromCacheCount: 0                                                                              |
|    loadTimeSeriesMetadataFromDiskCount: 0                                                                               |
|    loadTimeSeriesMetadataActualIOSize: 0                                                                                |
|    loadChunkFromCacheCount: 0                                                                                           |
|    loadChunkFromDiskCount: 0                                                                                            |
|    loadChunkActualIOSize: 0                                                                                             |
|    timeSeriesIndexFilteredRows: 0                                                                                       |
|    chunkIndexFilteredRows: 0                                                                                            |
|    pageIndexFilteredRows: 0                                                                                             |
|    rowScanFilteredRows: 0                                                                                               |
|    [PlanNodeId 69]: IdentitySinkNode(IdentitySinkOperator)                                                              |
|        CPU Time: 0.988 ms                                                                                               |
|        output: 18 rows                                                                                                  |
|        HasNext() Called Count: 9                                                                                        |
|        Next() Called Count: 8                                                                                           |
|        Estimated Memory Size: 131072                                                                                    |
|        DownStreamPlanNodeId: 66                                                                                         |
|      [PlanNodeId 55]: CollectNode(CollectOperator)                                                                      |
|          CPU Time: 0.954 ms                                                                                             |
|          output: 18 rows                                                                                                |
|          HasNext() Called Count: 9                                                                                      |
|          Next() Called Count: 8                                                                                         |
|          Estimated Memory Size: 131072                                                                                  |
|        [PlanNodeId 64]: ExchangeNode(ExchangeOperator)                                                                  |
|            CPU Time: 0.569 ms                                                                                          |
|            output: 12 rows                                                                                              |
|            HasNext() Called Count: 5                                                                                    |
|            Next() Called Count: 4                                                                                       |
|            Estimated Memory Size: 131072                                                                                |
|            size_in_bytes: 3264                                                                                          |
|        [PlanNodeId 65]: ExchangeNode(ExchangeOperator)                                                                  |
|            CPU Time: 0.354 ms                                                                                          |
|            output: 6 rows                                                                                               |
|            HasNext() Called Count: 3                                                                                    |
|            Next() Called Count: 2                                                                                       |
|            Estimated Memory Size: 131072                                                                                |
|            size_in_bytes: 1632                                                                                          |
|                                                                                                                         |
|FRAGMENT-INSTANCE[Id: 20260722_064913_00105_1.3.0][IP: 127.0.0.1:10730][DataRegion: 1][State: FINISHED]                  |
|  Total Wall Time: 32 ms                                                                                                 |
|  Cost of initDataQuerySource: 0.224 ms                                                                                  |
|  Seq File(unclosed): 0, Seq File(closed): 2                                                                             |
|  UnSeq File(unclosed): 0, UnSeq File(closed): 0                                                                         |
|  ready queued time: 0.025 ms, blocked queued time: 0.000 ms                                                             |
|  Query Statistics:                                                                                                      |
|    loadBloomFilterFromCacheCount: 2                                                                                     |
|    loadBloomFilterFromDiskCount: 0                                                                                     |
|    loadBloomFilterActualIOSize: 0                                                                                       |
|    loadBloomFilterTime: 0.018                                                                                           |
|    loadTimeSeriesMetadataAlignedDiskSeqCount: 4                                                                         |
|    loadTimeSeriesMetadataAlignedDiskSeqTime: 0.189                                                                      |
|    loadTimeSeriesMetadataFromCacheCount: 18                                                                             |
|    loadTimeSeriesMetadataFromDiskCount: 2                                                                               |
|    loadTimeSeriesMetadataActualIOSize: 0                                                                                |
|    alignedTimeSeriesMetadataModificationTime: 0.026                                                                     |
|    constructAlignedChunkReadersDiskCount: 4                                                                             |
|    constructAlignedChunkReadersDiskTime: 3.251                                                                          |
|    loadChunkFromCacheCount: 18                                                                                          |
|    loadChunkFromDiskCount: 0                                                                                            |
|    loadChunkActualIOSize: 0                                                                                             |
|    pageReadersDecodeAlignedDiskCount: 4                                                                                 |
|    pageReadersDecodeAlignedDiskTime: 0.210                                                                              |
|    timeSeriesIndexFilteredRows: 0                                                                                       |
|    chunkIndexFilteredRows: 0                                                                                            |
|    pageIndexFilteredRows: 0                                                                                             |
|    rowScanFilteredRows: 0                                                                                               |
|    [PlanNodeId 67]: IdentitySinkNode(IdentitySinkOperator)                                                              |
|        CPU Time: 5.150 ms                                                                                               |
|        output: 12 rows                                                                                                  |
|        HasNext() Called Count: 9                                                                                        |
|        Next() Called Count: 8                                                                                           |
|        Estimated Memory Size: 327680                                                                                    |
|        DownStreamPlanNodeId: 64                                                                                         |
|      [PlanNodeId 54]: DeviceTableScanNode(TableScanOperator)                                                            |
|          CPU Time: 5.136 ms                                                                                             |
|          output: 12 rows                                                                                                |
|          HasNext() Called Count: 9                                                                                      |
|          Next() Called Count: 8                                                                                         |
|          Estimated Memory Size: 327680                                                                                  |
|          DeviceNumber: 4                                                                                                |
|          CurrentDeviceIndex: 3                                                                                          |
|                                                                                                                         |
|FRAGMENT-INSTANCE[Id: 20260722_064913_00105_1.4.0][IP: 127.0.0.1:10730][DataRegion: 2][State: FINISHED]                  |
|  Total Wall Time: 32 ms                                                                                                 |
|  Cost of initDataQuerySource: 0.397 ms                                                                                  |
|  Seq File(unclosed): 0, Seq File(closed): 1                                                                             |
|  UnSeq File(unclosed): 0, UnSeq File(closed): 0                                                                         |
|  ready queued time: 0.075 ms, blocked queued time: 0.000 ms                                                             |
|  Query Statistics:                                                                                                      |
|    loadBloomFilterFromCacheCount: 0                                                                                     |
|    loadBloomFilterFromDiskCount: 0                                                                                     |
|    loadBloomFilterActualIOSize: 0                                                                                       |
|    loadBloomFilterTime: 0.000                                                                                           |
|    loadTimeSeriesMetadataAlignedDiskSeqCount: 2                                                                         |
|    loadTimeSeriesMetadataAlignedDiskSeqTime: 0.313                                                                      |
|    loadTimeSeriesMetadataFromCacheCount: 10                                                                             |
|    loadTimeSeriesMetadataFromDiskCount: 0                                                                               |
|    loadTimeSeriesMetadataActualIOSize: 0                                                                                |
|    alignedTimeSeriesMetadataModificationTime: 0.046                                                                     |
|    constructAlignedChunkReadersDiskCount: 2                                                                             |
|    constructAlignedChunkReadersDiskTime: 2.307                                                                          |
|    loadChunkFromCacheCount: 10                                                                                          |
|    loadChunkFromDiskCount: 0                                                                                            |
|    loadChunkActualIOSize: 0                                                                                             |
|    pageReadersDecodeAlignedDiskCount: 2                                                                                 |
|    pageReadersDecodeAlignedDiskTime: 0.129                                                                              |
|    timeSeriesIndexFilteredRows: 0                                                                                       |
|    chunkIndexFilteredRows: 0                                                                                            |
|    pageIndexFilteredRows: 0                                                                                             |
|    rowScanFilteredRows: 0                                                                                               |
|    [PlanNodeId 68]: IdentitySinkNode(IdentitySinkOperator)                                                              |
|        CPU Time: 4.187 ms                                                                                               |
|        output: 6 rows                                                                                                   |
|        HasNext() Called Count: 5                                                                                        |
|        Next() Called Count: 4                                                                                           |
|        Estimated Memory Size: 327680                                                                                    |
|        DownStreamPlanNodeId: 65                                                                                         |
|      [PlanNodeId 53]: DeviceTableScanNode(TableScanOperator)                                                            |
|          CPU Time: 4.172 ms                                                                                             |
|          output: 6 rows                                                                                                 |
|          HasNext() Called Count: 5                                                                                      |
|          Next() Called Count: 4                                                                                         |
|          Estimated Memory Size: 327680                                                                                  |
|          DeviceNumber: 2                                                                                                |
|          CurrentDeviceIndex: 1                                                                                          |
+-------------------------------------------------------------------------------------------------------------------------+

3.3 JSON Format

Using EXPLAIN ANALYZE (FORMAT JSON) returns structured information such as plan phase time consumption, fragment instance statistics, and operator statistics. The JSON format is supported since V2.0.11.

3.3.1 Default JSON Output

EXPLAIN ANALYZE (FORMAT JSON) SELECT * FROM t1;

The top-level JSON structure is as follows:

FieldType/OccurrenceDescription
planStatisticsobjectTime consumption of query analysis, partition fetching, schema fetching, logical planning, logical optimization, distributed planning, dispatch, and other phases
fragmentInstancesCountnumberNumber of fragment instances for which statistics are returned
fragmentInstancesarrayExecution statistics of each fragment instance

The main fields of planStatistics are as follows:

FieldType/OccurrenceDescription
analyzeCostMsplanStatisticsSQL analysis time, in ms
fetchPartitionCostMsplanStatisticsTime to fetch partition information, in ms
fetchSchemaCostMsplanStatisticsTime to fetch schema information, in ms
logicalPlanCostMsplanStatisticsLogical plan generation time, in ms
logicalOptimizationCostMsplanStatisticsLogical optimization time, in ms
distributionPlanCostMsplanStatisticsDistributed plan generation time, in ms
dispatchCostMsplanStatisticsFragment dispatch time, in ms

The main fields of fragmentInstances[] are as follows:

FieldType/OccurrenceDescription
idfragmentInstances[]fragment instance id
ipfragmentInstances[]IP of the node that executed this fragment instance
dataRegionfragmentInstances[]Corresponding DataRegion
statefragmentInstances[]Final state of the fragment instance
totalWallTimeMsfragmentInstances[]Total wall time, in ms
initDataQuerySourceCostMsfragmentInstances[]Data source initialization time, in ms
initDataQuerySourceRetryCountfragmentInstances[]Number of data source initialization retries. Only output when greater than 0
seqFileUnclosed, seqFileClosed, unseqFileUnclosed, unseqFileClosedfragmentInstances[]Number of sequential and out-of-order files involved
readyQueuedTimeMs, blockQueuedTimeMsfragmentInstances[]Ready / block queue waiting time, in ms
queryStatisticsfragmentInstances[]Query statistics such as scanning, filtering, chunk/page reader
operatorsfragmentInstances[]Operator tree and execution statistics of each operator

operators is a tree structure corresponding to the plan tree. The main fields are as follows:

FieldType/OccurrenceDescription
planNodeIdoperatorsCorresponding plan node id
nodeTypeoperatorsplan node type
operatorTypeoperatorsActual executed operator type
countoperatorsOperator statistics aggregation count. Only output when present
cpuTimeMsoperatorsOperator CPU execution time, in ms
outputRowsoperatorsNumber of output rows
hasNextCalledCount, nextCalledCountoperatorsNumber of operator iteration calls
estimatedMemorySizeoperatorsEstimated memory usage. Only output when non-zero
specifiedInfooperatorsOperator-specific statistics. Only output when non-empty
childrenoperatorsChild operator array

Taking table1 in the sample data as an example:

EXPLAIN ANALYZE (FORMAT JSON) SELECT * FROM table1;
+---------------+
|Explain Analyze|
+---------------+
{
  "planStatistics": {
    "analyzeCostMs": 4.948,
    "fetchPartitionCostMs": 2.104,
    "fetchSchemaCostMs": 13.321,
    "logicalPlanCostMs": 2.264,
    "logicalOptimizationCostMs": 7.941,
    "distributionPlanCostMs": 1.434,
    "dispatchCostMs": 9.023
  },
  "fragmentInstancesCount": 3,
  "fragmentInstances": [
    {
      "id": "20260722_064302_00101_1.2.0",
      "ip": "127.0.0.1:10730",
      "dataRegion": "virtual_data_region",
      "state": "FINISHED",
      "totalWallTimeMs": 97,
      "initDataQuerySourceCostMs": 0.0,
      "seqFileUnclosed": 0,
      "seqFileClosed": 0,
      "unseqFileUnclosed": 0,
      "unseqFileClosed": 0,
      "readyQueuedTimeMs": 0.858,
      "blockQueuedTimeMs": 71.752,
      "queryStatistics": {
        "timeSeriesIndexFilteredRows": 0,
        "chunkIndexFilteredRows": 0,
        "pageIndexFilteredRows": 0
      },
      "operators": {
        "planNodeId": "69",
        "nodeType": "IdentitySinkNode",
        "operatorType": "IdentitySinkOperator",
        "cpuTimeMs": 6.082,
        "outputRows": 18,
        "hasNextCalledCount": 9,
        "nextCalledCount": 8,
        "estimatedMemorySize": 131072,
        "specifiedInfo": {
          "DownStreamPlanNodeId": "66"
        },
        "children": [
          {
            "planNodeId": "55",
            "nodeType": "CollectNode",
            "operatorType": "CollectOperator",
            "cpuTimeMs": 6.065,
            "outputRows": 18,
            "hasNextCalledCount": 9,
            "nextCalledCount": 8,
            "estimatedMemorySize": 131072,
            "children": [
              {
                "planNodeId": "64",
                "nodeType": "ExchangeNode",
                "operatorType": "ExchangeOperator",
                "cpuTimeMs": 1.119,
                "outputRows": 12,
                "hasNextCalledCount": 5,
                "nextCalledCount": 4,
                "estimatedMemorySize": 131072,
                "specifiedInfo": {
                  "size_in_bytes": "3264"
                }
              },
              {
                "planNodeId": "65",
                "nodeType": "ExchangeNode",
                "operatorType": "ExchangeOperator",
                "cpuTimeMs": 4.909,
                "outputRows": 6,
                "hasNextCalledCount": 3,
                "nextCalledCount": 2,
                "estimatedMemorySize": 131072,
                "specifiedInfo": {
                  "size_in_bytes": "1632"
                }
              }
            ]
          }
        ]
      }
    },
    {
      "id": "20260722_064302_00101_1.3.0",
      "ip": "127.0.0.1:10730",
      "dataRegion": "1",
      "state": "FINISHED",
      "totalWallTimeMs": 63,
      "initDataQuerySourceCostMs": 0.338,
      "seqFileUnclosed": 0,
      "seqFileClosed": 2,
      "unseqFileUnclosed": 0,
      "unseqFileClosed": 0,
      "readyQueuedTimeMs": 0.273,
      "blockQueuedTimeMs": 0.0,
      "queryStatistics": {
        "timeSeriesIndexFilteredRows": 0,
        "chunkIndexFilteredRows": 0,
        "pageIndexFilteredRows": 0
      },
      "operators": {
        "planNodeId": "67",
        "nodeType": "IdentitySinkNode",
        "operatorType": "IdentitySinkOperator",
        "cpuTimeMs": 57.338,
        "outputRows": 12,
        "hasNextCalledCount": 9,
        "nextCalledCount": 8,
        "estimatedMemorySize": 327680,
        "specifiedInfo": {
          "DownStreamPlanNodeId": "64"
        },
        "children": [
          {
            "planNodeId": "54",
            "nodeType": "DeviceTableScanNode",
            "operatorType": "TableScanOperator",
            "cpuTimeMs": 57.248,
            "outputRows": 12,
            "hasNextCalledCount": 9,
            "nextCalledCount": 8,
            "estimatedMemorySize": 327680,
            "specifiedInfo": {
              "DeviceNumber": "4",
              "CurrentDeviceIndex": "3"
            }
          }
        ]
      }
    },
    {
      "id": "20260722_064302_00101_1.4.0",
      "ip": "127.0.0.1:10730",
      "dataRegion": "2",
      "state": "FINISHED",
      "totalWallTimeMs": 79,
      "initDataQuerySourceCostMs": 0.231,
      "seqFileUnclosed": 0,
      "seqFileClosed": 1,
      "unseqFileUnclosed": 0,
      "unseqFileClosed": 0,
      "readyQueuedTimeMs": 0.038,
      "blockQueuedTimeMs": 0.0,
      "queryStatistics": {
        "timeSeriesIndexFilteredRows": 0,
        "chunkIndexFilteredRows": 0,
        "pageIndexFilteredRows": 0
      },
      "operators": {
        "planNodeId": "68",
        "nodeType": "IdentitySinkNode",
        "operatorType": "IdentitySinkOperator",
        "cpuTimeMs": 66.387,
        "outputRows": 6,
        "hasNextCalledCount": 5,
        "nextCalledCount": 4,
        "estimatedMemorySize": 327680,
        "specifiedInfo": {
          "DownStreamPlanNodeId": "65"
        },
        "children": [
          {
            "planNodeId": "53",
            "nodeType": "DeviceTableScanNode",
            "operatorType": "TableScanOperator",
            "cpuTimeMs": 66.362,
            "outputRows": 6,
            "hasNextCalledCount": 5,
            "nextCalledCount": 4,
            "estimatedMemorySize": 327680,
            "specifiedInfo": {
              "DeviceNumber": "2",
              "CurrentDeviceIndex": "1"
            }
          }
        ]
      }
    }
  ]
}
+---------------+

3.3.2 VERBOSE JSON Output

When using EXPLAIN ANALYZE VERBOSE (FORMAT JSON), the top-level structure is the same as the non-verbose JSON, but queryStatistics supplements finer-grained statistics beyond the basic filtered row counts, including bloom filter, time series metadata, chunk, page reader, modification, and actual IO size information.

The main differences between VERBOSE and non-VERBOSE JSON output are as follows:

Output ModeTop-level StructurequeryStatistics Field GranularityTypical Fields
EXPLAIN ANALYZE (FORMAT JSON)planStatistics, fragmentInstancesCount, fragmentInstancesDefault statistics fieldstimeSeriesIndexFilteredRows, chunkIndexFilteredRows, pageIndexFilteredRows
EXPLAIN ANALYZE VERBOSE (FORMAT JSON)Same as non-VERBOSEMore detailed scanning, reading, and filtering statisticsloadBloomFilterFromCacheCount, loadTimeSeriesMetadataFromCacheCount, loadChunkFromDiskCount, pageReadersDecodeAlignedMemCount, rowScanFilteredRows

Taking table1 in the sample data as an example:

EXPLAIN ANALYZE VERBOSE (FORMAT JSON) SELECT * FROM table1;
+---------------+
|Explain Analyze|
+---------------+
{
  "planStatistics": {
    "analyzeCostMs": 3.505,
    "fetchPartitionCostMs": 2.003,
    "fetchSchemaCostMs": 9.198,
    "logicalPlanCostMs": 1.481,
    "logicalOptimizationCostMs": 6.684,
    "distributionPlanCostMs": 0.711,
    "dispatchCostMs": 8.32
  },
  "fragmentInstancesCount": 3,
  "fragmentInstances": [
    {
      "id": "20260722_064502_00103_1.2.0",
      "ip": "127.0.0.1:10730",
      "dataRegion": "virtual_data_region",
      "state": "FINISHED",
      "totalWallTimeMs": 48,
      "initDataQuerySourceCostMs": 0.0,
      "seqFileUnclosed": 0,
      "seqFileClosed": 0,
      "unseqFileUnclosed": 0,
      "unseqFileClosed": 0,
      "readyQueuedTimeMs": 0.209,
      "blockQueuedTimeMs": 17.997,
      "queryStatistics": {
        "loadBloomFilterFromCacheCount": 0,
        "loadBloomFilterFromDiskCount": 0,
        "loadBloomFilterActualIOSize": 0,
        "loadBloomFilterTimeMs": 0.0,
        "loadTimeSeriesMetadataFromCacheCount": 0,
        "loadTimeSeriesMetadataFromDiskCount": 0,
        "loadTimeSeriesMetadataActualIOSize": 0,
        "loadChunkFromCacheCount": 0,
        "loadChunkFromDiskCount": 0,
        "loadChunkActualIOSize": 0,
        "timeSeriesIndexFilteredRows": 0,
        "chunkIndexFilteredRows": 0,
        "pageIndexFilteredRows": 0,
        "rowScanFilteredRows": 0
      },
      "operators": {
        "planNodeId": "69",
        "nodeType": "IdentitySinkNode",
        "operatorType": "IdentitySinkOperator",
        "cpuTimeMs": 26.368,
        "outputRows": 18,
        "hasNextCalledCount": 9,
        "nextCalledCount": 8,
        "estimatedMemorySize": 131072,
        "specifiedInfo": {
          "DownStreamPlanNodeId": "66"
        },
        "children": [
          {
            "planNodeId": "55",
            "nodeType": "CollectNode",
            "operatorType": "CollectOperator",
            "cpuTimeMs": 26.32,
            "outputRows": 18,
            "hasNextCalledCount": 9,
            "nextCalledCount": 8,
            "estimatedMemorySize": 131072,
            "children": [
              {
                "planNodeId": "64",
                "nodeType": "ExchangeNode",
                "operatorType": "ExchangeOperator",
                "cpuTimeMs": 0.47,
                "outputRows": 12,
                "hasNextCalledCount": 5,
                "nextCalledCount": 4,
                "estimatedMemorySize": 131072,
                "specifiedInfo": {
                  "size_in_bytes": "3264"
                }
              },
              {
                "planNodeId": "65",
                "nodeType": "ExchangeNode",
                "operatorType": "ExchangeOperator",
                "cpuTimeMs": 25.802,
                "outputRows": 6,
                "hasNextCalledCount": 3,
                "nextCalledCount": 2,
                "estimatedMemorySize": 131072,
                "specifiedInfo": {
                  "size_in_bytes": "1632"
                }
              }
            ]
          }
        ]
      }
    },
    {
      "id": "20260722_064502_00103_1.3.0",
      "ip": "127.0.0.1:10730",
      "dataRegion": "1",
      "state": "FINISHED",
      "totalWallTimeMs": 21,
      "initDataQuerySourceCostMs": 0.232,
      "seqFileUnclosed": 0,
      "seqFileClosed": 2,
      "unseqFileUnclosed": 0,
      "unseqFileClosed": 0,
      "readyQueuedTimeMs": 0.007,
      "blockQueuedTimeMs": 0.0,
      "queryStatistics": {
        "loadBloomFilterFromCacheCount": 2,
        "loadBloomFilterFromDiskCount": 0,
        "loadBloomFilterActualIOSize": 0,
        "loadBloomFilterTimeMs": 0.02,
        "loadTimeSeriesMetadataAlignedDiskSeqCount": 4,
        "loadTimeSeriesMetadataAlignedDiskSeqTimeMs": 0.483,
        "loadTimeSeriesMetadataFromCacheCount": 18,
        "loadTimeSeriesMetadataFromDiskCount": 2,
        "loadTimeSeriesMetadataActualIOSize": 0,
        "alignedTimeSeriesMetadataModificationTimeMs": 0.061,
        "constructAlignedChunkReadersDiskCount": 4,
        "constructAlignedChunkReadersDiskTimeMs": 2.693,
        "loadChunkFromCacheCount": 18,
        "loadChunkFromDiskCount": 0,
        "loadChunkActualIOSize": 0,
        "pageReadersDecodeAlignedDiskCount": 4,
        "pageReadersDecodeAlignedDiskTimeMs": 0.22,
        "timeSeriesIndexFilteredRows": 0,
        "chunkIndexFilteredRows": 0,
        "pageIndexFilteredRows": 0,
        "rowScanFilteredRows": 0
      },
      "operators": {
        "planNodeId": "67",
        "nodeType": "IdentitySinkNode",
        "operatorType": "IdentitySinkOperator",
        "cpuTimeMs": 5.002,
        "outputRows": 12,
        "hasNextCalledCount": 9,
        "nextCalledCount": 8,
        "estimatedMemorySize": 327680,
        "specifiedInfo": {
          "DownStreamPlanNodeId": "64"
        },
        "children": [
          {
            "planNodeId": "54",
            "nodeType": "DeviceTableScanNode",
            "operatorType": "TableScanOperator",
            "cpuTimeMs": 4.94,
            "outputRows": 12,
            "hasNextCalledCount": 9,
            "nextCalledCount": 8,
            "estimatedMemorySize": 327680,
            "specifiedInfo": {
              "DeviceNumber": "4",
              "CurrentDeviceIndex": "3"
            }
          }
        ]
      }
    },
    {
      "id": "20260722_064502_00103_1.4.0",
      "ip": "127.0.0.1:10730",
      "dataRegion": "2",
      "state": "FINISHED",
      "totalWallTimeMs": 32,
      "initDataQuerySourceCostMs": 0.253,
      "seqFileUnclosed": 0,
      "seqFileClosed": 1,
      "unseqFileUnclosed": 0,
      "unseqFileClosed": 0,
      "readyQueuedTimeMs": 0.027,
      "blockQueuedTimeMs": 0.0,
      "queryStatistics": {
        "loadBloomFilterFromCacheCount": 0,
        "loadBloomFilterFromDiskCount": 0,
        "loadBloomFilterActualIOSize": 0,
        "loadBloomFilterTimeMs": 0.0,
        "loadTimeSeriesMetadataAlignedDiskSeqCount": 2,
        "loadTimeSeriesMetadataAlignedDiskSeqTimeMs": 0.188,
        "loadTimeSeriesMetadataFromCacheCount": 10,
        "loadTimeSeriesMetadataFromDiskCount": 0,
        "loadTimeSeriesMetadataActualIOSize": 0,
        "alignedTimeSeriesMetadataModificationTimeMs": 0.037,
        "constructAlignedChunkReadersDiskCount": 2,
        "constructAlignedChunkReadersDiskTimeMs": 1.807,
        "loadChunkFromCacheCount": 10,
        "loadChunkFromDiskCount": 0,
        "loadChunkActualIOSize": 0,
        "pageReadersDecodeAlignedDiskCount": 2,
        "pageReadersDecodeAlignedDiskTimeMs": 0.62,
        "timeSeriesIndexFilteredRows": 0,
        "chunkIndexFilteredRows": 0,
        "pageIndexFilteredRows": 0,
        "rowScanFilteredRows": 0
      },
      "operators": {
        "planNodeId": "68",
        "nodeType": "IdentitySinkNode",
        "operatorType": "IdentitySinkOperator",
        "cpuTimeMs": 3.652,
        "outputRows": 6,
        "hasNextCalledCount": 5,
        "nextCalledCount": 4,
        "estimatedMemorySize": 327680,
        "specifiedInfo": {
          "DownStreamPlanNodeId": "65"
        },
        "children": [
          {
            "planNodeId": "53",
            "nodeType": "DeviceTableScanNode",
            "operatorType": "TableScanOperator",
            "cpuTimeMs": 3.633,
            "outputRows": 6,
            "hasNextCalledCount": 5,
            "nextCalledCount": 4,
            "estimatedMemorySize": 327680,
            "specifiedInfo": {
              "DeviceNumber": "2",
              "CurrentDeviceIndex": "1"
            }
          }
        ]
      }
    }
  ]
}

4. Scenario Examples

4.1 CTE Query Plan

When EXPLAIN (FORMAT JSON) analyzes a query containing a materialized CTE, the output uses the wrapped structure of cteQueries + mainQuery.

Taking table1 and table2 in the sample data as an example:

EXPLAIN (FORMAT JSON)
WITH cte1 AS MATERIALIZED (SELECT * FROM table2)
SELECT * FROM table1
WHERE table1.device_id IN (SELECT device_id FROM cte1);
+-----------------+
|distribution plan|
+-----------------+
{
  "cteQueries": [
    {
      "name": "cte1",
      "plan": {
        "name": "OutputNode-4",
        "id": "4",
        "properties": {
          "OutputColumns": [
            "time",
            "region",
            "plant_id",
            "device_id",
            "model_id",
            "maintenance",
            "temperature",
            "humidity",
            "status",
            "arrival_time"
          ],
          "OutputSymbols": [
            "time",
            "region",
            "plant_id",
            "device_id",
            "model_id",
            "maintenance",
            "temperature",
            "humidity",
            "status",
            "arrival_time"
          ]
        },
        "children": [
          {
            "name": "CollectNode-33",
            "id": "33",
            "children": [
              {
                "name": "ExchangeNode-40",
                "id": "40",
                "children": [
                  {
                    "name": "DeviceTableScanNode-32",
                    "id": "32",
                    "properties": {
                      "QualifiedTableName": "database1.table2",
                      "OutputSymbols": [
                        "time",
                        "region",
                        "plant_id",
                        "device_id",
                        "model_id",
                        "maintenance",
                        "temperature",
                        "humidity",
                        "status",
                        "arrival_time"
                      ],
                      "DeviceNumber": "3",
                      "ScanOrder": "ASC",
                      "PushDownOffset": "0",
                      "PushDownLimit": "0",
                      "PushDownLimitToEachDevice": "false",
                      "RegionId": "1"
                    }
                  }
                ]
              },
              {
                "name": "ExchangeNode-41",
                "id": "41",
                "children": [
                  {
                    "name": "DeviceTableScanNode-31",
                    "id": "31",
                    "properties": {
                      "QualifiedTableName": "database1.table2",
                      "OutputSymbols": [
                        "time",
                        "region",
                        "plant_id",
                        "device_id",
                        "model_id",
                        "maintenance",
                        "temperature",
                        "humidity",
                        "status",
                        "arrival_time"
                      ],
                      "DeviceNumber": "3",
                      "ScanOrder": "ASC",
                      "PushDownOffset": "0",
                      "PushDownLimit": "0",
                      "PushDownLimitToEachDevice": "false",
                      "RegionId": "2"
                    }
                  }
                ]
              }
            ]
          }
        ]
      }
    }
  ],
  "mainQuery": {
    "name": "OutputNode-12",
    "id": "12",
    "properties": {
      "OutputColumns": [
        "time",
        "region",
        "plant_id",
        "device_id",
        "model_id",
        "maintenance",
        "temperature",
        "humidity",
        "status",
        "arrival_time"
      ],
      "OutputSymbols": [
        "time",
        "region",
        "plant_id",
        "device_id",
        "model_id",
        "maintenance",
        "temperature",
        "humidity",
        "status",
        "arrival_time"
      ]
    },
    "children": [
      {
        "name": "ProjectNode-35",
        "id": "35",
        "properties": {
          "OutputSymbols": [
            "time",
            "region",
            "plant_id",
            "device_id",
            "model_id",
            "maintenance",
            "temperature",
            "humidity",
            "status",
            "arrival_time"
          ],
          "Expressions": [
            "\"time\"",
            "\"region\"",
            "\"plant_id\"",
            "\"device_id\"",
            "\"model_id\"",
            "\"maintenance\"",
            "\"temperature\"",
            "\"humidity\"",
            "\"status\"",
            "\"arrival_time\""
          ]
        },
        "children": [
          {
            "name": "FilterNode-138",
            "id": "138",
            "properties": {
              "Predicate": "\"expr\""
            },
            "children": [
              {
                "name": "SemiJoinNode-109",
                "id": "109",
                "children": [
                  {
                    "name": "ExchangeNode-218",
                    "id": "218",
                    "children": [
                      {
                        "name": "MergeSortNode-197",
                        "id": "197",
                        "properties": {
                          "OrderBy": "{orderBy\u003d[device_id], orderings\u003d{device_id\u003dASC NULLS LAST}}"
                        },
                        "children": [
                          {
                            "name": "ExchangeNode-216",
                            "id": "216",
                            "children": [
                              {
                                "name": "DeviceTableScanNode-196",
                                "id": "196",
                                "properties": {
                                  "QualifiedTableName": "database1.table1",
                                  "OutputSymbols": [
                                    "time",
                                    "region",
                                    "plant_id",
                                    "device_id",
                                    "model_id",
                                    "maintenance",
                                    "temperature",
                                    "humidity",
                                    "status",
                                    "arrival_time"
                                  ],
                                  "DeviceNumber": "4",
                                  "ScanOrder": "ASC",
                                  "PushDownOffset": "0",
                                  "PushDownLimit": "0",
                                  "PushDownLimitToEachDevice": "true",
                                  "RegionId": "1"
                                }
                              }
                            ]
                          },
                          {
                            "name": "ExchangeNode-217",
                            "id": "217",
                            "children": [
                              {
                                "name": "DeviceTableScanNode-195",
                                "id": "195",
                                "properties": {
                                  "QualifiedTableName": "database1.table1",
                                  "OutputSymbols": [
                                    "time",
                                    "region",
                                    "plant_id",
                                    "device_id",
                                    "model_id",
                                    "maintenance",
                                    "temperature",
                                    "humidity",
                                    "status",
                                    "arrival_time"
                                  ],
                                  "DeviceNumber": "2",
                                  "ScanOrder": "ASC",
                                  "PushDownOffset": "0",
                                  "PushDownLimit": "0",
                                  "PushDownLimitToEachDevice": "true",
                                  "RegionId": "2"
                                }
                              }
                            ]
                          }
                        ]
                      }
                    ]
                  },
                  {
                    "name": "ExchangeNode-219",
                    "id": "219",
                    "children": [
                      {
                        "name": "SortNode-137",
                        "id": "137",
                        "properties": {
                          "OrderBy": "{orderBy\u003d[device_id_3], orderings\u003d{device_id_3\u003dASC NULLS FIRST}}"
                        },
                        "children": [
                          {
                            "name": "ProjectNode-6",
                            "id": "6",
                            "properties": {
                              "OutputSymbols": [
                                "device_id_3"
                              ],
                              "Expressions": [
                                "\"device_id_3\""
                              ]
                            },
                            "children": [
                              {
                                "name": "CteScanNode-2",
                                "id": "2"
                              }
                            ]
                          }
                        ]
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  }
}
+-----------------+

4.2 Prepared Statement and Dynamic SQL

When analyzing prepared statements and dynamic SQL via EXECUTE or EXECUTE IMMEDIATE, the specified output format continues to take effect after the statement is expanded, and will not fall back to the default GRAPHVIZ or TEXT format.

PREPARE explain_json_stmt FROM SELECT * FROM table1 WHERE device_id = ?;
EXPLAIN (FORMAT JSON) EXECUTE explain_json_stmt USING '101';

EXPLAIN ANALYZE (FORMAT JSON) EXECUTE IMMEDIATE 'SELECT * FROM table1 WHERE device_id = ?' USING '101';

Where:

  • EXPLAIN (FORMAT JSON) EXECUTE ... returns a plan node JSON object.

  • EXPLAIN ANALYZE (FORMAT JSON) EXECUTE IMMEDIATE ... returns a JSON object containing planStatistics, fragmentInstancesCount, and fragmentInstances.

  1. EXPLAIN (FORMAT JSON) EXECUTE ... output structure example:
+-----------------+
|distribution plan|
+-----------------+
{
  "name": "OutputNode-5",
  "id": "5",
  "properties": {
    "OutputColumns": [
      "time",
      "region",
      "plant_id",
      "device_id",
      "model_id",
      "maintenance",
      "temperature",
      "humidity",
      "status",
      "arrival_time"
    ],
    "OutputSymbols": [
      "time",
      "region",
      "plant_id",
      "device_id",
      "model_id",
      "maintenance",
      "temperature",
      "humidity",
      "status",
      "arrival_time"
    ]
  },
  "children": [
    {
      "name": "DeviceTableScanNode-46",
      "id": "46",
      "properties": {
        "QualifiedTableName": "database1.table1",
        "OutputSymbols": [
          "time",
          "region",
          "plant_id",
          "device_id",
          "model_id",
          "maintenance",
          "temperature",
          "humidity",
          "status",
          "arrival_time"
        ],
        "DeviceNumber": "3",
        "ScanOrder": "ASC",
        "PushDownOffset": "0",
        "PushDownLimit": "0",
        "PushDownLimitToEachDevice": "false",
        "RegionId": "1"
      }
    }
  ]
}
+-----------------+
  1. EXPLAIN ANALYZE (FORMAT JSON) EXECUTE IMMEDIATE ... output structure example:
+---------------+
|Explain Analyze|
+---------------+
{
  "planStatistics": {
    "analyzeCostMs": 2.904,
    "fetchPartitionCostMs": 1.35,
    "fetchSchemaCostMs": 5.259,
    "logicalPlanCostMs": 1.123,
    "logicalOptimizationCostMs": 6.157,
    "distributionPlanCostMs": 0.571,
    "dispatchCostMs": 5.909
  },
  "fragmentInstancesCount": 1,
  "fragmentInstances": [
    {
      "id": "20260722_065558_00118_1.2.0",
      "ip": "127.0.0.1:10730",
      "dataRegion": "1",
      "state": "FINISHED",
      "totalWallTimeMs": 10,
      "initDataQuerySourceCostMs": 1.768,
      "seqFileUnclosed": 0,
      "seqFileClosed": 2,
      "unseqFileUnclosed": 0,
      "unseqFileClosed": 0,
      "readyQueuedTimeMs": 0.059,
      "blockQueuedTimeMs": 0.0,
      "queryStatistics": {
        "timeSeriesIndexFilteredRows": 0,
        "chunkIndexFilteredRows": 0,
        "pageIndexFilteredRows": 0
      },
      "operators": {
        "planNodeId": "74",
        "nodeType": "IdentitySinkNode",
        "operatorType": "IdentitySinkOperator",
        "cpuTimeMs": 9.193,
        "outputRows": 10,
        "hasNextCalledCount": 7,
        "nextCalledCount": 6,
        "estimatedMemorySize": 327680,
        "specifiedInfo": {
          "DownStreamPlanNodeId": "73"
        },
        "children": [
          {
            "planNodeId": "68",
            "nodeType": "DeviceTableScanNode",
            "operatorType": "TableScanOperator",
            "cpuTimeMs": 9.055,
            "outputRows": 10,
            "hasNextCalledCount": 7,
            "nextCalledCount": 6,
            "estimatedMemorySize": 327680,
            "specifiedInfo": {
              "DeviceNumber": "3",
              "CurrentDeviceIndex": "2"
            }
          }
        ]
      }
    }
  ]
}
+---------------+

4.3 JSON Display in CLI

The CLI outputs regular query results in tabular format by default. For JSON-format query analysis results, if the JSON body continues to be placed in table cells, each row would carry | borders, which is not conducive to copying, saving, and JSON parsing.

The CLI switches to raw JSON display when the following conditions are met:

ConditionDescription
The result set has only one columnAvoids affecting normal multi-column query display
The column name is distribution plan or Explain AnalyzeOnly matches the result columns of EXPLAIN / EXPLAIN ANALYZE
The first result value trimmed starts with { or [Only enables raw output for JSON object / array content

Raw JSON display rules:

  • The CLI still outputs the column name header and outer separator line, so users can identify the current column as distribution plan or Explain Analyze.

  • The JSON body is output line by line as-is, without adding | table borders.

  • After the JSON ends, a separator line and row count statistics are output.

  • Non-JSON EXPLAIN, default text EXPLAIN ANALYZE, and regular query results still use the original table output.

The differences between raw JSON output and regular table output are as follows:

Output TypeApplicable ResultDisplay MethodCopy and Parse
Regular table outputRegular query results, default EXPLAIN, default EXPLAIN ANALYZEEach row's content is placed inside table bordersSuitable for human viewing, not suitable for direct JSON copy parsing
Raw JSON outputEXPLAIN (FORMAT JSON), EXPLAIN ANALYZE (FORMAT JSON)Retains column name header, JSON body has no table bordersSuitable for direct copying, saving, or handing to a JSON parser

Example:

start-cli.sh -sql_dialect table -e "EXPLAIN (FORMAT JSON) SELECT time, device_id, temperature FROM database1.table1"
+-----------------+
|distribution plan|
+-----------------+
{
  "name": "OutputNode-4",
  "id": "4",
  "properties": {
    "OutputColumns": [
      "time",
      "device_id",
      "temperature"
    ],
    "OutputSymbols": [
      "time",
      "device_id",
      "temperature"
    ]
  },
  "children": [
    {
      "name": "CollectNode-42",
      "id": "42",
      "children": [
        {
          "name": "ExchangeNode-49",
          "id": "49",
          "children": [
            {
              "name": "DeviceTableScanNode-41",
              "id": "41",
              "properties": {
                "QualifiedTableName": "database1.table1",
                "OutputSymbols": [
                  "time",
                  "device_id",
                  "temperature"
                ],
                "DeviceNumber": "4",
                "ScanOrder": "ASC",
                "PushDownOffset": "0",
                "PushDownLimit": "0",
                "PushDownLimitToEachDevice": "false",
                "RegionId": "1"
              }
            }
          ]
        },
        {
          "name": "ExchangeNode-50",
          "id": "50",
          "children": [
            {
              "name": "DeviceTableScanNode-40",
              "id": "40",
              "properties": {
                "QualifiedTableName": "database1.table1",
                "OutputSymbols": [
                  "time",
                  "device_id",
                  "temperature"
                ],
                "DeviceNumber": "2",
                "ScanOrder": "ASC",
                "PushDownOffset": "0",
                "PushDownLimit": "0",
                "PushDownLimitToEachDevice": "false",
                "RegionId": "2"
              }
            }
          ]
        }
      ]
    }
  ]
}
+-----------------+

4.4 Illegal Format Combinations

EXPLAIN and EXPLAIN ANALYZE support different formats. Illegal format combinations return a clear error.

StatementDefault FormatSupported FormatsUnsupported Formats
EXPLAINGRAPHVIZGRAPHVIZ, JSONTEXT, XML, other unknown formats
EXPLAIN ANALYZETEXTTEXT, JSONGRAPHVIZ, XML, other unknown formats

Example:

EXPLAIN (FORMAT TEXT) SELECT * FROM table1;
EXPLAIN ANALYZE (FORMAT GRAPHVIZ) SELECT * FROM table1;
EXPLAIN (FORMAT XML) SELECT * FROM table1;

Corresponding errors:

Msg: org.apache.iotdb.jdbc.IoTDBSQLException: 701: Invalid EXPLAIN format: TEXT. Supported formats: GRAPHVIZ, JSON
Msg: org.apache.iotdb.jdbc.IoTDBSQLException: 701: Invalid EXPLAIN ANALYZE format: GRAPHVIZ. Supported formats: TEXT, JSON
Msg: org.apache.iotdb.jdbc.IoTDBSQLException: 701: Invalid EXPLAIN format: XML. Supported formats: GRAPHVIZ, JSON

5. FAQ

5.1 What to do when a query times out?

EXPLAIN ANALYZE actually executes the query, so it may also fail to return complete results when the query times out. To assist troubleshooting, IoTDB writes the current analysis results to a dedicated log in text form at certain time intervals; the log interval is calculated based on the query timeout, ensuring at least two result records before timeout.

When encountering a timeout, handle it in the following order:

  1. Check the staged analysis results for the corresponding query in logs/log_explain_analyze.log.

  2. If there are no results in the log, check whether only the lib package was replaced during the upgrade, and conf/logback-datanode.xml was not replaced synchronously.

  3. After replacing the configuration, no restart is required. Wait for the configuration hot reload to complete, then execute EXPLAIN ANALYZE VERBOSE.

5.2 What is the difference between WALL TIME and CPU TIME?

CPU time refers to the time the program actually occupies the CPU for computation during execution, representing the processor resources actually consumed by the program.

Wall time refers to the real physical time from when the program starts execution to when it ends, including resource waiting time.

WALL TIME < CPU TIME is common in parallel execution scenarios. For example, if a query fragment is executed in parallel by two threads, 10 seconds of physical time pass, but the two threads each occupy one CPU core running for 10 seconds, then the CPU TIME is about 20 seconds, and the WALL TIME is about 10 seconds.

WALL TIME > CPU TIME is common in resource waiting scenarios. For example, a query fragment enters the blocked queue due to insufficient memory or waiting for upstream data, or enters the ready queue due to insufficient query thread resources. During the wait, no CPU is occupied, but physical time still passes.

5.3 Does EXPLAIN ANALYZE have additional overhead?

The statistics collection itself has almost no significant additional overhead. The EXPLAIN ANALYZE operator collects the statistics already available from the original query, and traverses via next without printing the query results, so there is usually no significant difference in time consumption compared to directly executing the same query.

Note that the analyzed query is still fully executed and normally consumes CPU, memory, and IO resources. When evaluating the impact on the production environment, refer to the resource consumption of the original query itself.

5.4 Which metrics should I focus on for IO time consumption?

Metrics involving IO time consumption mainly include loadBloomFilterActualIOSize, loadBloomFilterTime, loadTimeSeriesMetadataAlignedDiskSeqTime, loadTimeSeriesMetadataAlignedDiskUnseqTime, loadTimeSeriesMetadataActualIOSize, alignedTimeSeriesMetadataModificationTime, constructAlignedChunkReadersDiskTime, and loadChunkActualIOSize.

TimeSeriesMetadata loading statistics are separated for sequential and out-of-order files, but Chunk reading is not yet separately counted for sequential and out-of-order proportions; this can be estimated through the sequential/out-of-order ratio of TimeSeriesMetadata.

5.5 How to observe the impact of out-of-order data on query performance?

Out-of-order data mainly produces two types of impact:

  1. During query, an additional merge sort needs to be done in memory.

  2. Out-of-order data produces time range overlaps between data blocks, causing some statistics to be unusable for directly skipping data blocks that do not meet conditions, or for directly calculating aggregate values.

Currently, there is no direct observation metric specifically for the impact of out-of-order data. Usually, you can execute a query once when out-of-order data exists, and then execute the query again after the out-of-order data is merged, and evaluate by comparing the time consumption before and after.