You need to enable JavaScript to run this app.
ByteHouse 企业版

ByteHouse 企业版

复制全文
执行计划
执行计划 EXPLAIN
复制全文
执行计划 EXPLAIN

ByteHouse 支持通过 EXPLAIN 语句为 SQL 语句生成对应的执行计划,帮助您了解 ByteHouse 如何执行查询,便于您针对性优化 SQL 语句。本文以 TPCH-Q1 中的 SQL 为例,演示了如何使用不同类型的 EXPLAIN 语句。

功能概述

在 ByteHouse 中,优化器(Query Optimizer)通过规则优化(Rule-Based Optimization,RBO)、代价优化(Cost-Based Optimization,CBO)、原生分布式计划协同、及高阶能力(动态过滤下推/物化视图改写),实现全链路查询优化。开启优化器后,执行 EXPLAIN 语句将为 SQL 语句生成对应的执行计划,展示执行计划的详细信息,并生成更高效的执行计划,可帮助开发人员快速定位 SQL 性能瓶颈,可针对性优化索引设计、表达式复杂度或分布式执行策略,确保以最小资源开销快速返回结果。更多优化器的介绍和使用说明请参见优化器
ByteHouse 当前支持了以下类型的 EXPLAIN 语句:

类型

定义

EXPLAIN

用于展示逻辑执行计划。

EXPLAIN DISTRIBUTED

用于展示分布式执行计划。

EXPLAIN ANALYZE

用于展示带有运行时信息的执行计划,可细分为以下类型:

EXPLAIN PIPELINE

该语句用于展示物理执行计划。

EXPLAIN AST

转储查询的抽象语法树(AST),支持所有类型的查询,不仅仅是 SELECT

EXPLAIN SYNTAX

返回经过语法优化后的查询。

EXPLAIN METADATA

该语句用于展示 SQL Analyzer 阶段解析的一些信息,解析的信息主要包括,库名,表明,列名,函数名,settings 等信息。

语法
EXPLAIN [DISTRIBUTED | ANALYZE | PIPELINE | AST | SYNTAX | METADATA ] [setting = value, ...]
    [
      SELECT ... |
      tableFunction(...) [COLUMNS (...)] [ORDER BY ...] [PARTITION BY ...] [PRIMARY KEY] [SAMPLE BY ...] [TTL ...]
    ]
    [FORMAT ...]

参数说明

参数

是否必填

说明

DISTRIBUTED

ANALYZE

PIPELINE

setting = value

设置自定义查询执行参数。
例如,您可以使用 json 设置是否以 JSON 格式打印计划,设置为 1 表示打印 JSON 格式的计划,设置为 0 表示不打印,该参数设置后的效果与设置 FORMAT 相同。示例:json = 1

SELECT

二选一

与 tableFunction(...) 二选一。设置为需要分析的 SELECT 查询语句。

tableFunction(...)

二选一

与 SELECT 二选一。设置为需要分析的表函数。

COLUMNS (...)

定义表函数需要返回的列名和类型。

ORDER BY

定义表函数的排序键。

PARTITION BY

定义表函数的数据分区规则。

PRIMARY KEY

设置表函数的索引主键。

SAMPLE BY

声明表函数的采样表达式。

TTL

配置表函数的数据过期策略。

FORMAT

定义将结果转换成指定输出格式。

示例

EXPLAIN json=0
SELECT
    l_returnflag,
    l_linestatus,
    sum(l_quantity) AS sum_qty,
    sum(l_extendedprice) AS sum_base_price,
    sum(l_extendedprice * (1 - l_discount)) AS sum_disc_price,
    sum((l_extendedprice * (1 - l_discount)) * (1 + l_tax)) AS sum_charge,
    avg(l_quantity) AS avg_qty,
    avg(l_extendedprice) AS avg_price,
    avg(l_discount) AS avg_disc,
    count(*) AS count_order
FROM lineitem
WHERE l_shipdate <= (toDate('1998-12-01') - toIntervalDay('90'))
GROUP BY
    l_returnflag,
    l_linestatus
ORDER BY
    l_returnflag ASC,
    l_linestatus ASC

输出结果
Image

EXPLAIN 类型

EXPLAIN DISTRIBUTED

该语句用于展示分布式执行计划。

语法

EXPLAIN DISTRIBUTED <SQL>;

示例

EXPLAIN DISTRIBUTED
SELECT
    l_returnflag,
    l_linestatus,
    sum(l_quantity) AS sum_qty,
    sum(l_extendedprice) AS sum_base_price,
    sum(l_extendedprice * (1 - l_discount)) AS sum_disc_price,
    sum((l_extendedprice * (1 - l_discount)) * (1 + l_tax)) AS sum_charge,
    avg(l_quantity) AS avg_qty,
    avg(l_extendedprice) AS avg_price,
    avg(l_discount) AS avg_disc,
    count(*) AS count_order
FROM lineitem
WHERE l_shipdate <= (toDate('1998-12-01') - toIntervalDay('90'))
GROUP BY
    l_returnflag,
    l_linestatus
ORDER BY
    l_returnflag ASC,
    l_linestatus ASC 

输出结果
Image

EXPLAIN ANALYZE

EXPLAIN ANALYZE 用于展示带有运行时信息的执行计划,也支持通过 EXPLAIN ANALYZE DISTRIBUTED 展示带有运行时信息的分布式执行计划,支持 EXPLAIN ANALYZE PIPELINE 展示带有运行时信息的物理执行计划。
这三类语句支持的通用 setting 参数如下:

参数

是否必填

说明

json

设置是否以 JSON 格式打印计划,默认值为 0,表示不以 JSON 格式输出,设置为 1 表示打印 JSON 格式的计划。示例:json = 1

stats

设置是否输出统计信息行数和 cost,默认值为 1,表示输出,设置为 0 表示不输出。示例:stats = 1

profile

设置是否输出执行时 profiles,默认值为 1,表示输出,设置为 0 表示不输出。示例:profile = 1

verbose

设置是否输出输出逻辑计划 node 详细内容,默认值为 1,表示输出,设置为 0 表示不输出。示例:verbose = 1

indexes

设置是否打印索引使用情况,设置为 1 表示打印,设置为 0 表示不打印。示例:indexes = 1

segment_id

设置 segment id,可在打印分布式计划时指定打印具体 segment 内容。

segment_profile

设置是否在打印分布式计划打印 segment 耗时,设置为 1 表示打印,设置为 0 表示不打印。示例:segment_profile = 1

EXPLAIN ANALYZE

该语句用于展示带有运行时信息的执行计划。具体字段说明请参见 Explain Analyze字段说明

语法

EXPLAIN ANALYZE <SQL>;

参数说明

除了通用参数外,EXPLAIN ANALYZE 还支持设置以下 setting 参数:

  • processor_profile_events:设置是否输出执行计划执行时每个PlanNode上的ProfileEvents metrics。设置为 1 时,系统将输出相关内容并按节点做聚合,设置为 0 时,表示不输出。示例:processor_profile_events = 1

示例

EXPLAIN ANALYZE
SELECT
    l_returnflag,
    l_linestatus,
    sum(l_quantity) AS sum_qty,
    sum(l_extendedprice) AS sum_base_price,
    sum(l_extendedprice * (1 - l_discount)) AS sum_disc_price,
    sum((l_extendedprice * (1 - l_discount)) * (1 + l_tax)) AS sum_charge,
    avg(l_quantity) AS avg_qty,
    avg(l_extendedprice) AS avg_price,
    avg(l_discount) AS avg_disc,
    count(*) AS count_order
FROM lineitem
WHERE l_shipdate <= (toDate('1998-12-01') - toIntervalDay('90'))
GROUP BY
    l_returnflag,
    l_linestatus
ORDER BY
    l_returnflag ASC,
    l_linestatus ASC

输出结果
Image

EXPLAIN ANALYZE DISTRIBUTED

该语句用于展示带有运行时信息的分布式执行计划,具体字段说明请参见 Explain Analyze字段说明

语法

EXPLAIN ANALYZE DISTRIBUTED <SQL>;

参数说明

除了通用参数外,EXPLAIN ANALYZE DISTRIBUTED 还支持设置以下 setting 参数:

  • processor_profile_events:设置是否输出执行计划执行时每个PlanNode上的ProfileEvents metrics。设置为 1 时,系统将输出相关内容并按节点做聚合,设置为 0 时,表示不输出。示例:processor_profile_events = 1
  • profile_events_list:可用于输出分布式计划执行时的 ProfileEvents,默认是聚合的。如需分别显示每个节点的 ProfileEvents,可设置 aggregate_profiles=0。示例:profile_events_list='QueryAnalyzerTime',如果有多个参数值,可使用逗号(,)分隔。
  • aggregate_profiles:设置 aggregate_profiles = 1,可打印每个 worker 聚合后的 profile,设置 aggregate_profiles = 0,系统将分别打印出每个 worker 的 profiles。

示例

EXPLAIN ANALYZE DISTRIBUTED
SELECT
    l_returnflag,
    l_linestatus,
    sum(l_quantity) AS sum_qty,
    sum(l_extendedprice) AS sum_base_price,
    sum(l_extendedprice * (1 - l_discount)) AS sum_disc_price,
    sum((l_extendedprice * (1 - l_discount)) * (1 + l_tax)) AS sum_charge,
    avg(l_quantity) AS avg_qty,
    avg(l_extendedprice) AS avg_price,
    avg(l_discount) AS avg_disc,
    count(*) AS count_order
FROM lineitem
WHERE l_shipdate <= (toDate('1998-12-01') - toIntervalDay('90'))
GROUP BY
    l_returnflag,
    l_linestatus
ORDER BY
    l_returnflag ASC,
    l_linestatus ASC

输出结果
Image

EXPLAIN ANALYZE PIPELINE

该语句用于展示带有运行时信息的物理执行计划。该功能在 EXPLAIN PIPELINE 的基础上,增加执行信息,打印出每个 processor 具体的执行信息。

语法

EXPLAIN ANALYZE PIPELINE <SQL>;

参数说明

除了通用参数外,EXPLAIN ANALYZE PIPELINE 还支持设置以下 setting 参数:

  • aggregate_profiles:设置 aggregate_profiles = 1,可打印每个 worker 聚合后的 profile,设置 aggregate_profiles = 0,系统将分别打印出每个 worker 的 profiles。
  • profile_events_list:可用于输出分布式计划执行时的 ProfileEvents,默认是聚合的。如需分别显示每个节点的 ProfileEvents,可设置 aggregate_profiles=0。示例:profile_events_list='QueryAnalyzerTime',如果有多个参数值,可使用逗号(,)分隔。

示例

EXPLAIN ANALYZE PIPELINE
SELECT
    l_returnflag,
    l_linestatus,
    sum(l_quantity) AS sum_qty,
    sum(l_extendedprice) AS sum_base_price,
    sum(l_extendedprice * (1 - l_discount)) AS sum_disc_price,
    sum((l_extendedprice * (1 - l_discount)) * (1 + l_tax)) AS sum_charge,
    avg(l_quantity) AS avg_qty,
    avg(l_extendedprice) AS avg_price,
    avg(l_discount) AS avg_disc,
    count(*) AS count_order
FROM lineitem
WHERE l_shipdate <= (toDate('1998-12-01') - toIntervalDay('90'))
GROUP BY
    l_returnflag,
    l_linestatus
ORDER BY
    l_returnflag ASC,
    l_linestatus ASC

输出结果
Image

EXPLAIN PIPELINE

该语句用于展示物理执行计划。

语法

EXPLAIN PIPELINE <SQL>;

示例

EXPLAIN PIPELINE
SELECT
    l_returnflag,
    l_linestatus,
    sum(l_quantity) AS sum_qty,
    sum(l_extendedprice) AS sum_base_price,
    sum(l_extendedprice * (1 - l_discount)) AS sum_disc_price,
    sum((l_extendedprice * (1 - l_discount)) * (1 + l_tax)) AS sum_charge,
    avg(l_quantity) AS avg_qty,
    avg(l_extendedprice) AS avg_price,
    avg(l_discount) AS avg_disc,
    count(*) AS count_order
FROM lineitem
WHERE l_shipdate <= (toDate('1998-12-01') - toIntervalDay('90'))
GROUP BY
    l_returnflag,
    l_linestatus
ORDER BY
    l_returnflag ASC,
    l_linestatus ASC

输出结果
Image

EXPLAIN AST

转储查询的抽象语法树(AST),支持所有类型的查询,不仅仅是 SELECT

语法

EXPLAIN AST <SQL>;

示例

EXPLAIN AST
SELECT
    l_returnflag,
    l_linestatus,
    sum(l_quantity) AS sum_qty,
    sum(l_extendedprice) AS sum_base_price,
    sum(l_extendedprice * (1 - l_discount)) AS sum_disc_price,
    sum((l_extendedprice * (1 - l_discount)) * (1 + l_tax)) AS sum_charge,
    avg(l_quantity) AS avg_qty,
    avg(l_extendedprice) AS avg_price,
    avg(l_discount) AS avg_disc,
    count(*) AS count_order
FROM lineitem
WHERE l_shipdate <= (toDate('1998-12-01') - toIntervalDay('90'))
GROUP BY
    l_returnflag,
    l_linestatus
ORDER BY
    l_returnflag ASC,
    l_linestatus ASC

输出结果

Image

EXPLAIN SYNTAX

返回经过语法优化后的查询。

语法

EXPLAIN SYNTAX <SQL>;

示例

EXPLAIN SYNTAX
SELECT
    l_returnflag,
    l_linestatus,
    sum(l_quantity) AS sum_qty,
    sum(l_extendedprice) AS sum_base_price,
    sum(l_extendedprice * (1 - l_discount)) AS sum_disc_price,
    sum((l_extendedprice * (1 - l_discount)) * (1 + l_tax)) AS sum_charge,
    avg(l_quantity) AS avg_qty,
    avg(l_extendedprice) AS avg_price,
    avg(l_discount) AS avg_disc,
    count(*) AS count_order
FROM lineitem
WHERE l_shipdate <= (toDate('1998-12-01') - toIntervalDay('90'))
GROUP BY
    l_returnflag,
    l_linestatus
ORDER BY
    l_returnflag ASC,
    l_linestatus ASC

输出结果
Image

EXPLAIN METADATA

该语句用于展示 SQL Analyzer 阶段解析的一些信息,解析的信息主要包括,库名,表明,列名,函数名,settings 等信息。

使用限制

  • 仅在 EXPLAIN METADATA <SQL> 形式下使用;
  • 只对 SELECT 和 INSERT SELECT 的查询生效。

语法

EXPLAIN METADATA <SQL>;

参数说明

EXPLAIN METADATA 支持设置以下 setting 参数:

  • format_json:设置 format_json = 1 表示输出内容是 JSON 格式。
  • lineage:设置是否输出 SQL 血缘关系信息,设置为 1 表示展示,设置为 0 表示不展示。示例:lineage = 1

示例 1

explain metadata select t1.a, t2.b from metadata t1 join metadata2 t2 on t1.a=t2.a settings enable_optimizer=1;

输出结果
Image
其中的字段说明如下:

  • tables:查询中涉及的表,array 类型。
  • databases:tables 字段中表对应的数据库,array(String) 类型。
  • column_lists:tables 字段中表在当前查询中使用到的列,array(array(String)) 类型。
  • used_function_names:查询中用到的函数名,array(String) 类型。
  • settings:查询中生效的 settings 名,map(string, string) 类型。
  • insert_info:insert的库名,表名和列名,array(array(String)) 类型。

示例 2

EXPLAIN METADATA format_json = 1, lineage = 1
WITH t3 AS
    (
        SELECT
            count() AS a,
            sum(b) AS b
        FROM cache2
        GROUP BY c
    )
SELECT
    a,
    b
FROM
(
    (
        SELECT
            t3.b AS a,
            t2.b AS b
        FROM cache AS t2
        INNER JOIN t3 ON t2.a = t3.a
    )
    UNION ALL
    (
        SELECT 
            *
        FROM t3
    )
) AS t1
WHERE t1.a = 1
SETTINGS enable_optimizer = 1
FORMAT TabSeparatedRaw

输出结果

{
 "UsedTablesInfo" : [
  {
   "Database" : "test",
   "Table" : "cache",
   "Columns" : [
    "a",
    "b"
   ]
  },
  {
   "Database" : "test",
   "Table" : "cache2",
   "Columns" : [
    "b",
    "c"
   ]
  }
 ],
 "UsedFunctions" : [
  "count",
  "equals",
  "sum"
 ],
 "UsedSettings" : {
  "enable_optimizer" : "1"
 },
 "InsertInfo" : {
 },
 "FunctionsInfo" : [

 ],
 "LineageInfo" : {
  "TableSources" : [
   {
    "Database" : "test",
    "Table" : "cache2",
    "Columns" : [
     {
      "Id" : 3,
      "Name" : "b"
     },
     {
      "Id" : 2,
      "Name" : "c"
     }
    ]
   },
   {
    "Database" : "test",
    "Table" : "cache",
    "Columns" : [
     {
      "Id" : 1,
      "Name" : "a"
     },
     {
      "Id" : 0,
      "Name" : "b"
     }
    ]
   }
  ],
  "ExpressionSources" : [
   {
    "Sources" : [
     {
      "Database" : "test",
      "Table" : "cache2"
     }
    ],
    "Expression" : [
     {
      "Id" : 4,
      "Name" : "expr#count()"
     }
    ]
   }
  ],
  "OutputLineageInfo" : [
   {
    "Name" : "b",
    "SourceIds" : [
     3,
     0
    ]
   },
   {
    "Name" : "a",
    "SourceIds" : [
     4,
     3
    ]
   }
  ],
  "InsertLinageInfo" : {
  }
 }
}

其中字段说明如下:

  • TableSources:查询中所有的表对应的原始列信息,所有的列(column)对应一个 ID。
  • ExpressionSources:查询中由表达式、常量、无法找到对应原始列信息的聚合函数信息,每个表达式也对应一个 ID。其中 Sources 字段包含了生成该表达式涉及的表信息。
  • OutputLineageInfo:查询所有输出的字段名和对应的原始列或表达式(expression)的 ID,其中 Name 为输出的字段名,SourceIds 为对应的列或表达式的 IDs。
  • InsertLinageInfo:insert select 插入语句中插入的表和列信息和对应 select 子句输出字段名的对应关系。InsertColumnName 为插入语句中对应的列名,InputName 为对应 OutputLineageInfo 中输出字段名。

最近更新时间:2025.07.29 10:56:50
这个页面对您有帮助吗?
有用
有用
无用
无用