Doris基础知识篇(10):执行计划
概念
doris-查询原理_doris 查询_longlovefilm的博客-CSDN博客
Doris 功能介绍-查询分析
:::success
- 执行计划从上到下生成,执行从下往上执行
- 在Doris中,FE负责查询的【解析、分析、优化、生成计划、调度】
- BE只负责【执行】
:::1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78mysql> desc graph select tbl1.k1, sum(tbl1.k2) from tbl1 join tbl2 on tbl1.k1 = tbl2.k1 group by tbl1.k1 order by tbl1.k1;
+---------------------------------------------------------------------------------------------------------------------------------+
| Explain String |
+---------------------------------------------------------------------------------------------------------------------------------+
| |
| ┌---------------┐ |
| │[9: ResultSink]│ |
| │[Fragment: 4] │ |
| │RESULT SINK │ |
| └---------------┘ |
| │ |
| ┌---------------------┐ |
| │[9: MERGING-EXCHANGE]│ |
| │[Fragment: 4] │ |
| └---------------------┘ |
| │ |
| ┌-------------------┐ |
| │[9: DataStreamSink]│ |
| │[Fragment: 3] │ |
| │STREAM DATA SINK │ |
| │ EXCHANGE ID: 09 │ |
| │ UNPARTITIONED │ |
| └-------------------┘ |
| │ |
| ┌-------------┐ |
| │[4: TOP-N] │ |
| │[Fragment: 3]│ |
| └-------------┘ |
| │ |
| ┌-------------------------------┐ |
| │[8: AGGREGATE (merge finalize)]│ |
| │[Fragment: 3] │ |
| └-------------------------------┘ |
| │ |
| ┌-------------┐ |
| │[7: EXCHANGE]│ |
| │[Fragment: 3]│ |
| └-------------┘ |
| │ |
| ┌-------------------┐ |
| │[7: DataStreamSink]│ |
| │[Fragment: 2] │ |
| │STREAM DATA SINK │ |
| │ EXCHANGE ID: 07 │ |
| │ HASH_PARTITIONED │ |
| └-------------------┘ |
| │ |
| ┌---------------------------------┐ |
| │[3: AGGREGATE (update serialize)]│ |
| │[Fragment: 2] │ |
| │STREAMING │ |
| └---------------------------------┘ |
| │ |
| ┌---------------------------------┐ |
| │[2: HASH JOIN] │ |
| │[Fragment: 2] │ |
| │join op: INNER JOIN (PARTITIONED)│ |
| └---------------------------------┘ |
| ┌----------┴----------┐ |
| ┌-------------┐ ┌-------------┐ |
| │[5: EXCHANGE]│ │[6: EXCHANGE]│ |
| │[Fragment: 2]│ │[Fragment: 2]│ |
| └-------------┘ └-------------┘ |
| │ │ |
| ┌-------------------┐ ┌-------------------┐ |
| │[5: DataStreamSink]│ │[6: DataStreamSink]│ |
| │[Fragment: 0] │ │[Fragment: 1] │ |
| │STREAM DATA SINK │ │STREAM DATA SINK │ |
| │ EXCHANGE ID: 05 │ │ EXCHANGE ID: 06 │ |
| │ HASH_PARTITIONED │ │ HASH_PARTITIONED │ |
| └-------------------┘ └-------------------┘ |
| │ │ |
| ┌-----------------┐ ┌-----------------┐ |
| │[0: OlapScanNode]│ │[1: OlapScanNode]│ |
| │[Fragment: 0] │ │[Fragment: 1] │ |
| │TABLE: tbl1 │ │TABLE: tbl2 │ |
| └-----------------┘ └-----------------┘ |
+----------------------------------------------------------------------内容 含义 查询计划 查询计划是将SQL语言转换为数据库的具体执行计划。> SQL 是一个描述性语言,用户通过一个 SQL 来描述想获取的数据。而一个 SQL 的具体执行方式依赖于数据库的实现。而查询规划器就是用来决定数据库如何具体执行一个 SQL 的。
比如用户指定了一个 Join 算子,则查询规划器需要决定具体的 Join 算法,比如是 Hash Join,还是 Merge Sort Join;是使用 Shuffle 还是 Broadcast;Join 顺序是否需要调整以避免笛卡尔积;以及确定最终的在哪些节点执行等等。
|
| Fragment | FE会将具体的SQL语句的执行转化为对应的Fragment并下发到BE进行执行。BE上执行对应Fragment,并将结果汇聚返回给FE。
查询规划器会将「单机查询计划」转换为「分布式查询」,分布式查询计划由多个Fragment组成。
每个Fragment负责一部分的查询内容,它们之间通过ExchangeNode算子进行数据传输。Plan 分布式化的方法是增加 ExchangeNode,DataStreamSink 会将一个 Fragment 的数据发送到另一个 Fragment 的 ExchangeNode。> 之后,查询规划器会根据具体的算子执行方式、数据的具体分布,将单机查询计划转换为分布式查询计划。分布式查询计划是由多个 Fragment 组成的,每个 Fragment 负责查询计划的一部分,各个 Fragment 直接会通过 ExchangeNode 算子进行数据的传输。
如上图,我们将单机计划分成了两个 Fragment:F1 和 F2。两个 Fragment 之间通过一个 ExchangeNode 节点传输数据。
|
| Instance | 是Fragment进一步划分而来的最终的具体执行实例,划分成多个 Instance 有助于充分利用机器资源,提升一个 Fragment 的执行并发度。
看执行计划:全量扫描分桶时,每个分桶对应了一个instance
|
| Segment | Apache Doris 存储引擎采用类似 LSM 树的结构提供快速的数据写入支持。进行数据导入时,数据会先写入 Tablet 对应的 MemTable 中,当 MemTable 写满之后,会将 MemTable 里的数据刷写(Flush)到磁盘,生成一个个不超过 256MB 的不可变的 Segment 文件。 |
| catalog | 元数据的最高层对象,一般用来区分不同种类的元数据
在spark on doris中有两种catalog
1. doris_catalog,doris这种引擎的元数据,在spark on doris中catalog默认值就是doris_catalog
2. spark_catalog,hivemetastore的元数据
|
| cluster | 与doris的cluster是相同的含义,例如doris公共集群下有个叫common的cluster
spark_catalog下没有这个概念 |
:::success
一个SQL会先转换为查询计划,但是这个查询计划如果在单机上查询,就会非常低效;
所以一个查询计划会变为分布式查询计划,由多个Fragment分别执行,
但是,Fragment只表示查询计划,具体的查询操作还需要instance来执行,
每个Fragment的查询计划执行完后,需要将数据传输出去,
传出的Fragment时候使用DataStreamSink,接收的Fragment使用Exechange Node
执行计划由FE生成:
- PlanNodeTree
- PlanFragmentTree(分布式执行计划)
- DataSink:数据传输
- ExchangeNode:数据接收
:::