查询性能分析

1. 概述

查询分析用于帮助用户理解查询的执行机制和性能瓶颈,从而进行查询优化和性能调优。IoTDB 表模型提供两类查询分析语句:

  • EXPLAIN:预览查询 SQL 的执行计划,展示 IoTDB 如何组织数据检索和处理。

  • EXPLAIN ANALYZE:在 EXPLAIN 基础上真实执行查询,并展示查询执行过程中的时间、资源消耗和算子统计信息。

EXPLAIN 和 EXPLAIN ANALYZE 默认输出面向人工阅读,适合在 CLI 中直接查看。对于 Web Console、CI 回归测试、自动化性能诊断系统等需要稳定解析查询计划或执行统计的场景,可以使用 JSON 输出格式获取结构化结果。JSON 格式自 V2.0.11 起支持。

1.1 查询分析方式对比

与 Arthas 抽样等排查手段相比,EXPLAIN ANALYZE 无需部署额外组件,可以针对单条 SQL 进行分布式追踪,更适合定位具体查询的性能问题。

方法安装难度业务影响功能范围
EXPLAIN ANALYZE 语句低。无需安装额外组件,为 IoTDB 内置 SQL 语句低。只会影响当前分析的单条查询,对线上其他负载无影响支持分布式,可对单条 SQL 进行追踪
Arthas 抽样中。需要安装 Java Arthas 工具高。CPU 抽样可能会影响线上业务响应速度不支持分布式,仅支持对数据库整体查询负载和耗时进行分析

2. EXPLAIN

2.1 语法

EXPLAIN 命令用于查看 SQL 查询的分布式执行计划。执行计划以算子树的形式展示,描述 IoTDB 将如何执行查询。

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

其中:

参数说明
SELECT_STATEMENT需要分析的查询语句
FORMAT GRAPHVIZ以默认图形文本形式输出分布式计划,适合人工阅读
FORMAT JSON以 JSON 对象输出分布式计划,适合程序解析(自 V2.0.11 起支持)

FORMAT 后的格式名大小写不敏感,例如 FORMAT json 与 FORMAT JSON 等价。

2.2 默认 GRAPHVIZ 格式

EXPLAIN 默认格式为 GRAPHVIZ,执行后将得到 distribution plan 结果列。

以示例数据中的 table1 为例,以下两条语句等价:

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

执行如上语句后,输出如下:IoTDB 通过 DeviceTableScanNode 节点从不同数据分区读取数据,并通过 Collect 算子汇总后返回。

+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|                                                                                                                                                                                                                                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 格式

使用 EXPLAIN (FORMAT JSON) 可以返回分布式计划树的 JSON 表示。结果集为单列输出,JSON 格式下返回单行、单个 JSON 对象,便于 JDBC 客户端或自动化工具直接读取。

EXPLAIN (FORMAT JSON) 的顶层结构随查询类型变化:

场景顶层结构说明
普通查询plan node JSON object顶层直接是 OutputNode 等计划节点对象
包含 materialized CTE 的查询wrapper JSON object顶层包含 cteQueries 和 mainQuery,用于同时保留 CTE 子查询计划与主查询计划

每个 plan node 输出为一个 JSON object,基础字段如下:

字段类型/出现位置说明
namestring节点类型与 plan node id 拼接后的展示名,例如 OutputNode-4
idstringplan node id
propertiesobject节点属性。仅当节点存在可展示属性时输出
childrenarray子节点数组。仅当节点存在子节点时输出

常见 plan node 属性包括:

节点类型主要字段/属性
OutputNodeOutputColumns、OutputSymbols
TableScanNode / DeviceTableScanNodeQualifiedTableName、OutputSymbols、DeviceNumber、ScanOrder、TimePredicate、PushDownPredicate、PushDownOffset、PushDownLimit、PushDownLimitToEachDevice、RegionId
TreeDeviceViewScanNode除表扫描属性外,补充 TreeDB、MeasurementToColumnName
AggregationNodeOutputSymbols、Aggregators、GroupingKeys、Streamable、PreGroupedSymbols、Step
FilterNodePredicate
ProjectNodeOutputSymbols、Expressions
LimitNode / OffsetNodeCount
SortNode / MergeSortNodeOrderBy
JoinNodeJoinType、Criteria、OutputSymbols
UnionNodeOutputSymbols
ExplainAnalyzeNodeChildPermittedOutputs

当查询包含 materialized CTE 时,JSON 顶层不再直接是单个 plan node,而是包装为:

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

其中 cteQueries[].plan 与 mainQuery 均为 plan node JSON object。该结构用于同时保留 CTE 子查询计划与主查询计划。

以示例数据中的 table1 为例:

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 语法

EXPLAIN ANALYZE 是 IoTDB 查询引擎自带的性能分析 SQL。与 EXPLAIN 不同,它会真实执行对应查询计划并统计执行信息,可用于追踪一条查询的具体性能分布,辅助资源观察、性能调优和异常分析。

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

其中:

参数说明
SELECT_STATEMENT需要分析的查询语句
VERBOSE打印更详细的分析结果。不填写时会省略部分细粒度统计
FORMAT TEXT以默认文本形式输出分析结果,适合人工阅读
FORMAT JSON以 JSON 对象输出分析结果,适合程序解析(自 V2.0.11 起支持)

3.2 默认 TEXT 格式

EXPLAIN ANALYZE 默认格式为 TEXT,执行后将得到 Explain Analyze 结果列。结果由查询规划统计、fragment instance 统计、数据读取统计和算子树统计组成。

  • 查询规划统计

QueryStatistics 包含查询层面的统计信息:

字段类型/出现位置说明
Analyze Cost查询规划统计SQL 分析阶段的耗时
Fetch Partition Cost查询规划统计拉取分区表的耗时
Fetch Schema Cost查询规划统计拉取元数据以及权限校验的耗时
Logical Plan Cost查询规划统计构建逻辑计划的耗时
Logical Optimization Cost查询规划统计逻辑计划优化的耗时
Distribution Plan Cost查询规划统计构建分布式计划的耗时
Dispatch Cost查询规划统计分发 fragment instance 的耗时
Fragment Instances Count查询规划统计总查询分片数量,每个查询分片的信息会依次输出
  • Fragment instance 统计

FragmentInstance 是 IoTDB 一个查询分片的封装。每个查询分片都会输出一份执行信息,主要包含 fragment 统计和算子信息。

fragment 统计包括:

字段类型/出现位置说明
Total Wall Timefragment 统计该分片从开始执行到执行结束的物理时间
Cost of initDataQuerySourcefragment 统计构建查询文件列表的耗时
Seq File(unclosed)fragment 统计未封口的顺序文件数量
Seq File(closed)fragment 统计已封口的顺序文件数量
UnSeq File(unclosed)fragment 统计未封口的乱序文件数量
UnSeq File(closed)fragment 统计已封口的乱序文件数量
ready queued timefragment 统计查询分片所有 task 在 ready queue 中的总时长
blocked queued timefragment 统计查询分片所有 task 在 blocked queue 中的总时长
  • 数据读取统计

Query Statistics 明细字段包括:

字段类型/出现位置说明
loadBloomFilterFromCacheCountBloomFilter命中 BloomFilterCache 的次数
loadBloomFilterFromDiskCountBloomFilter从磁盘读取 BloomFilter 的次数
loadBloomFilterActualIOSizeBloomFilter从磁盘读取 BloomFilter 时产生的磁盘 IO,单位为 bytes
loadBloomFilterTimeBloomFilter读取 BloomFilter 并计算序列是否存在的总耗时,单位为 ms
loadTimeSeriesMetadataDiskSeqCountTimeSeriesMetadata从已封口顺序文件中加载的 TimeSeriesMetadata 数量
loadTimeSeriesMetadataDiskUnSeqCountTimeSeriesMetadata从已封口乱序文件中加载的 TimeSeriesMetadata 数量
loadTimeSeriesMetadataDiskSeqTimeTimeSeriesMetadata从已封口顺序文件中加载 TimeSeriesMetadata 的耗时
loadTimeSeriesMetadataDiskUnSeqTimeTimeSeriesMetadata从已封口乱序文件中加载 TimeSeriesMetadata 的耗时
loadTimeSeriesMetadataFromCacheCountTimeSeriesMetadata命中 TimeSeriesMetadataCache 的次数
loadTimeSeriesMetadataFromDiskCountTimeSeriesMetadata从磁盘读取 TimeSeriesMetadata 的次数
loadTimeSeriesMetadataActualIOSizeTimeSeriesMetadata从磁盘读取 TimeSeriesMetadata 时产生的磁盘 IO,单位为 bytes
TimeSeriesMetadataModificationTimeMods 文件读取 mods 文件的耗时
constructAlignedChunkReadersDiskCountChunk构造 ChunkReader 的次数
constructAlignedChunkReadersDiskTimeChunk构造 ChunkReader 的总耗时,包含磁盘 IO 和解压缩
pageReadersDecodeAlignedDiskCountChunk解码 page 的数量
pageReadersDecodeAlignedDiskTimeChunk解码 page 的总耗时
loadChunkFromCacheCountChunk命中 ChunkCache 的次数
loadChunkFromDiskCountChunk从磁盘读取 Chunk 的次数
loadChunkActualIOSizeChunk从磁盘读取 Chunk 时产生的磁盘 IO,单位为 bytes
  • 算子树统计

算子树统计包括:

字段类型/出现位置说明
CPU Time算子树统计当前算子的 CPU 执行耗时
output算子树统计当前算子的输出行数
HasNext() Called Count算子树统计当前算子 HasNext() 接口被调用的次数
Next() Called Count算子树统计当前算子 Next() 接口被调用的次数
Estimated Memory Size算子树统计当前算子的估算内存占用
节点专属统计信息算子树统计不同算子输出的定制统计字段,例如 DeviceNumber、CurrentDeviceIndex、OutputPlanNodeId、size_in_bytes 等

常见节点专属统计字段包括:

字段类型/出现位置说明
DeviceNumberTableScan 相关节点当前 table scan 涉及的设备数量
CurrentDeviceIndexTableScan 相关节点当前正在扫描的设备索引
OutputPlanNodeIdsink 节点sink 节点对应的下游接收数据节点
size_in_bytesexchange 节点exchange 节点接收到的 TsBlock 字节数,仅计算数据占用大小
TimeSeriesIndexFilteredRowsfilter 下推到 table scan 时的 table scan 节点通过序列元数据过滤掉的数据行数
ChunkIndexFilteredRowsfilter 下推到 table scan 时的 table scan 节点通过列块元数据过滤掉的数据行数
PageIndexFilteredRowsfilter 下推到 table scan 时的 table scan 节点通过页头内部统计信息过滤掉的数据行数
RowScanFilteredRowsfilter 下推到 table scan 且使用 VERBOSE 时的 table scan 节点逐行检查数据时被过滤掉的行数

实际输出字段会随查询类型、涉及的算子、是否使用 VERBOSE 以及是否触发过滤下推而变化。未触发对应逻辑时,相关字段可能不会出现在结果中。

  • 文本输出示例

以示例数据中的 table1 为例,以下两条语句等价:

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 输出示例

使用 VERBOSE 可以查看更细粒度的数据读取和过滤统计:

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 格式

使用 EXPLAIN ANALYZE (FORMAT JSON) 可以返回计划阶段耗时、fragment instance 统计、operator 统计等结构化信息。JSON 格式自 V2.0.11 起支持。

3.3.1 默认 JSON 输出

EXPLAIN ANALYZE (FORMAT JSON) SELECT * FROM t1;

顶层 JSON 结构如下:

字段类型/出现位置说明
planStatisticsobject查询分析、分区获取、schema 获取、逻辑规划、逻辑优化、分布式规划、dispatch 等阶段耗时
fragmentInstancesCountnumber返回统计信息的 fragment instance 数量
fragmentInstancesarray各 fragment instance 的执行统计

planStatistics 主要字段如下:

字段类型/出现位置说明
analyzeCostMsplanStatisticsSQL 分析耗时,单位 ms
fetchPartitionCostMsplanStatistics获取分区信息耗时,单位 ms
fetchSchemaCostMsplanStatistics获取 schema 信息耗时,单位 ms
logicalPlanCostMsplanStatistics逻辑计划生成耗时,单位 ms
logicalOptimizationCostMsplanStatistics逻辑优化耗时,单位 ms
distributionPlanCostMsplanStatistics分布式计划生成耗时,单位 ms
dispatchCostMsplanStatisticsfragment dispatch 耗时,单位 ms

fragmentInstances[] 主要字段如下:

字段类型/出现位置说明
idfragmentInstances[]fragment instance id
ipfragmentInstances[]执行该 fragment instance 的节点 IP
dataRegionfragmentInstances[]对应 DataRegion
statefragmentInstances[]fragment instance 最终状态
totalWallTimeMsfragmentInstances[]总 wall time,单位 ms
initDataQuerySourceCostMsfragmentInstances[]初始化数据源耗时,单位 ms
initDataQuerySourceRetryCountfragmentInstances[]初始化数据源重试次数。仅当大于 0 时输出
seqFileUnclosed、seqFileClosed、unseqFileUnclosed、unseqFileClosedfragmentInstances[]涉及的顺序和乱序文件数量
readyQueuedTimeMs、blockQueuedTimeMsfragmentInstances[]ready / block 队列等待时间,单位 ms
queryStatisticsfragmentInstances[]扫描、过滤、chunk/page reader 等查询统计
operatorsfragmentInstances[]operator tree 及每个 operator 的执行统计

operators 为与 plan tree 对应的树状结构,主要字段如下:

字段类型/出现位置说明
planNodeIdoperators对应 plan node id
nodeTypeoperatorsplan node 类型
operatorTypeoperators实际执行 operator 类型
countoperatorsoperator 统计聚合次数。仅当存在时输出
cpuTimeMsoperatorsoperator CPU 执行耗时,单位 ms
outputRowsoperators输出行数
hasNextCalledCount、nextCalledCountoperatorsoperator 迭代调用次数
estimatedMemorySizeoperators估算内存占用。仅非 0 时输出
specifiedInfooperatorsoperator 特有统计信息。仅非空时输出
childrenoperators子 operator 数组

以示例数据中的 table1 为例:

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 输出

当使用 EXPLAIN ANALYZE VERBOSE (FORMAT JSON) 时,顶层结构与非 verbose JSON 一致,但 queryStatistics 会在基础过滤行数外补充更细粒度统计,包括 bloom filter、time series metadata、chunk、page reader、modification 和实际 IO size 等信息。

VERBOSE 与非 VERBOSE JSON 输出的主要差异如下:

输出模式顶层结构queryStatistics 字段粒度典型字段
EXPLAIN ANALYZE (FORMAT JSON)planStatistics、fragmentInstancesCount、fragmentInstances默认统计字段timeSeriesIndexFilteredRows、chunkIndexFilteredRows、pageIndexFilteredRows
EXPLAIN ANALYZE VERBOSE (FORMAT JSON)与非 VERBOSE 一致更详细的扫描、读取和过滤统计loadBloomFilterFromCacheCount、loadTimeSeriesMetadataFromCacheCount、loadChunkFromDiskCount、pageReadersDecodeAlignedMemCount、rowScanFilteredRows

以示例数据中的 table1 为例:

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. 场景示例

4.1 CTE 查询计划

当 EXPLAIN (FORMAT JSON) 分析包含 materialized CTE 的查询时,输出会使用 cteQueries + mainQuery 的包装结构。

以示例数据中的 table1 和 table2 为例:

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 与动态 SQL

通过 EXECUTE 或 EXECUTE IMMEDIATE 分析预处理语句和动态 SQL 时,指定的输出格式会在语句展开后继续生效,不会退回默认的 GRAPHVIZ 或 TEXT 格式。

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';

其中:

  • EXPLAIN (FORMAT JSON) EXECUTE ... 返回 plan node JSON object。

  • EXPLAIN ANALYZE (FORMAT JSON) EXECUTE IMMEDIATE ... 返回包含 planStatistics、fragmentInstancesCount、fragmentInstances 的 JSON object。

  1. EXPLAIN (FORMAT JSON) EXECUTE ... 输出结构示例:
+-----------------+
|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 ... 输出结构示例:
+---------------+
|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 CLI 中的 JSON 展示

CLI 对普通查询结果默认按表格输出。对于 JSON 格式的查询分析结果,如果继续把 JSON 正文放入表格单元格,每一行都会带上 | 边框,不利于复制、保存和 JSON 解析。

当满足以下条件时,CLI 会切换为 raw JSON 展示:

条件说明
结果集只有一列避免影响普通多列查询展示
列名为 distribution plan 或 Explain Analyze仅匹配 EXPLAIN / EXPLAIN ANALYZE 的结果列
首个结果值 trim 后以 { 或 [ 开始仅对 JSON object / array 内容启用 raw 输出

raw JSON 展示规则:

  • CLI 仍输出列名表头和外层分隔线,用户可以识别当前列为 distribution plan 或 Explain Analyze。

  • JSON 正文逐行原样输出,不添加 | 表格边框。

  • JSON 结束后输出分隔线和行数统计。

  • 非 JSON 的 EXPLAIN、默认文本 EXPLAIN ANALYZE、普通查询结果仍走原有表格输出。

raw JSON 展示与普通表格输出的区别如下:

输出类型适用结果展示方式复制与解析
普通表格输出普通查询结果、默认 EXPLAIN、默认 EXPLAIN ANALYZE每一行内容都放在表格边框内适合人工查看,不适合直接作为 JSON 复制解析
raw JSON 输出EXPLAIN (FORMAT JSON)、EXPLAIN ANALYZE (FORMAT JSON)保留列名表头,JSON 正文不加表格边框适合直接复制、保存或交给 JSON parser 解析

示例:

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 非法格式组合

EXPLAIN 和 EXPLAIN ANALYZE 支持的格式不同。非法格式组合会返回明确错误。

语句默认格式支持格式不支持格式
EXPLAINGRAPHVIZGRAPHVIZ、JSONTEXT、XML、其他未知格式
EXPLAIN ANALYZETEXTTEXT、JSONGRAPHVIZ、XML、其他未知格式

示例:

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

对应报错:

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. 常见问题

5.1 查询超时时怎么办?

EXPLAIN ANALYZE 会真实执行查询,因此也可能在查询超时时无法返回完整结果。为辅助排查,IoTDB 会按一定时间间隔将当前分析结果以文本形式写入专用日志;日志间隔根据查询超时时间计算,可保证超时前至少记录两次结果。

遇到超时时,按以下顺序处理:

  1. 查看 logs/log_explain_analyze.log 中对应查询的阶段性分析结果。

  2. 如果日志中没有结果,检查升级时是否只替换了 lib 包,而未同步替换 conf/logback-datanode.xml。

  3. 替换配置后无需重启。等待配置热加载完成,再执行 EXPLAIN ANALYZE VERBOSE。

5.2 WALL TIME 和 CPU TIME 有什么区别?

CPU 时间指程序在执行过程中实际占用 CPU 进行计算的时间,表示程序实际消耗的处理器资源。

墙上时间指从程序开始执行到结束的真实物理时间,包括资源等待时间。

WALL TIME < CPU TIME 常见于并行执行场景。例如一个查询分片被两个线程并行执行,物理时间过去 10 秒,但两个线程各占用一个 CPU 核运行 10 秒,则 CPU TIME 约为 20 秒,WALL TIME 约为 10 秒。

WALL TIME > CPU TIME 常见于等待资源场景。例如查询分片因内存不足或等待上游数据进入 blocked queue,或者因查询线程资源不足进入 ready queue。等待期间不占用 CPU,但物理时间仍在流逝。

5.3 EXPLAIN ANALYZE 是否有额外开销?

统计信息采集本身几乎没有显著的额外开销。EXPLAIN ANALYZE 算子会收集原查询已有的统计信息,并通过 next 遍历但不打印查询结果,因此与直接执行同一查询的耗时通常没有显著差别。

需要注意的是,被分析的查询仍会完整执行并正常消耗 CPU、内存和 IO 资源。评估生产环境影响时,应以原查询本身的资源消耗为准。

5.4 IO 耗时主要关注哪些指标?

涉及 IO 耗时的指标主要包括 loadBloomFilterActualIOSize、loadBloomFilterTime、loadTimeSeriesMetadataAlignedDiskSeqTime、loadTimeSeriesMetadataAlignedDiskUnseqTime、loadTimeSeriesMetadataActualIOSize、alignedTimeSeriesMetadataModificationTime、constructAlignedChunkReadersDiskTime、loadChunkActualIOSize。

TimeSeriesMetadata 的加载分别统计顺序文件和乱序文件,但 Chunk 的读取暂时未分开统计顺序和乱序比例,可以通过 TimeSeriesMetadata 的顺乱序比例进行估算。

5.5 乱序数据对查询性能的影响如何观测?

乱序数据主要产生两类影响:

  1. 查询时需要在内存中多做一次归并排序。

  2. 乱序数据会产生数据块间的时间范围重叠,导致部分统计信息无法直接用于跳过不满足条件的数据块,或无法直接计算聚合值。

当前没有单独针对乱序数据影响的直接观测指标。通常可以在存在乱序数据时执行一次查询,待乱序数据合并完成后再次执行查询,通过前后耗时对比进行评估。