xinyiZzz commented on a change in pull request #6154:
URL: https://github.com/apache/incubator-doris/pull/6154#discussion_r666702437
##########
File path: docs/zh-CN/administrator-guide/runtime-filter.md
##########
@@ -0,0 +1,223 @@
+---
+{
+ "title": "Runtime Filter",
+ "language": "zh-CN"
+}
+---
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+# Runtime Filter
+Runtime Filter 是在 Doris 0.15 版本中正式加入的新功能。旨在为某些 Join
查询在运行时动态生成过滤条件,来减少扫描的数据量,避免不必要的I/O和网络传输,从而加速查询。
+
+它的设计、实现和效果可以参阅 [ISSUE
6116](https://github.com/apache/incubator-doris/issues/6116)。
+
+## 名词解释
+* FE:Frontend,Doris 的前端节点。负责元数据管理和请求接入。
+* BE:Backend,Doris 的后端节点。负责查询执行和数据存储。
+* 左表:Join查询时,左边的表。进行Probe操作。可被Join Reorder调整顺序。
+* 右表:Join查询时,右边的表。进行Build操作。可被Join Reorder调整顺序。
+* Fragment:FE会将具体的SQL语句的执行转化为对应的Fragment并下发到BE进行执行。BE上执行对应Fragment,并将结果汇聚返回给FE。
+* Join on clause: `A join B on A.a=B.b`中的`A.a=B.b`,在查询规划时基于此生成join
conjuncts,包含join Build和Probe使用的expr,其中Build expr在Runtime Filter中称为src
expr,Probe expr在Runtime Filter中称为target expr。
+
+## 原理
+Runtime Filter在查询规划时生成,在HashJoinNode中构建,在ScanNode中应用。
+
+举个例子,当前存在T1表与T2表的Join查询,它的Join方式为HashJoin,T1是一张事实表,数据行数为100000,T2是一张维度表,数据行数为100,Doris
join的实际情况是:
+```
+| > HashJoinNode <
+| | |
+| | 100000 | 2000
+| | |
+| OlapScanNode OlapScanNode
+| ^ ^
+| | 100000 | 2000
+| T1 T2
+|
+```
+显而易见对T2扫描数据要远远快于T1,如果我们主动等待一段时间再扫描T1,等T2将扫描的数据记录交给HashJoinNode后,HashJoinNode根据T2的数据计算出一个过滤条件,比如T2数据的最大和最小值,或者构建一个Bloom
Filter,接着将这个过滤条件发给等待扫描T1的ScanNode,后者应用这个过滤条件,将过滤后的数据交给HashJoinNode,从而减少probe
hash table的次数和网络开销,这个过滤条件就是Runtime Filter,效果如下:
+```
+| > HashJoinNode <
+| | |
+| | 6000 | 2000
+| | |
+| OlapScanNode OlapScanNode
+| ^ ^
+| | 100000 | 2000
+| T1 T2
+|
+```
+如果能将过滤条件(Runtime Filter)下推到存储引擎,则某些情况下可以利用索引来直接减少扫描的数据量,从而大大减少扫描耗时,效果如下:
+```
+| > HashJoinNode <
+| | |
+| | 6000 | 2000
+| | |
+| OlapScanNode OlapScanNode
+| ^ ^
+| | 6000 | 2000
+| T1 T2
+|
+```
+可见,和谓词下推、分区裁剪不同,Runtime Filter是在运行时动态生成的过滤条件,即在查询运行时解析join on
clause确定过滤表达式,并将表达式广播给正在读取左表的ScanNode,从而减少扫描的数据量,进而减少probe hash
table的次数,避免不必要的I/O和网络传输。
+
+Runtime Filter主要用于优化针对大表的join,如果左表的数据量太小,或者右表的数据量太大,则Runtime Filter可能不会取得预期效果。
+
+## 使用方式
+
+### 设置Session变量
+除`runtime_filter_type`外,其他查询选项用于调整Runtime
Filter在特定场景下达到最佳性能,通常只在性能测试后进行调整,针对资源密集型、运行耗时足够长且频率足够高的查询进行优化。
+
+#### 1.runtime_filter_type
+使用的Runtime Filter类型,包括Bloom Filter、MinMax Filter、IN
predicate三种类型,使用多个时用逗号分隔,注意需要加引号,例如:
+```
+set runtime_filter_type="BLOOM_FILTER,IN,MIN_MAX";
+```
+默认会保守的只使用IN predicate,部分情况下同时使用Bloom Filter、MinMax Filter、IN predicate时性能更高。
+
+- **Bloom Filter**: 有一定的误判率,导致过滤的数据比预期少一点,但不会导致最终结果不准确,在大部分情况下Bloom
Filter都可以提升性能或对性能没有显著影响,但在部分情况下会导致性能降低。
+ - Bloom Filter构建和应用的开销较高,所以当过滤率较低时,或者左表数据量较少时,Bloom Filter可能会导致性能降低。
+ - 目前只有左表的Key列应用Bloom Filter才能下推到存储引擎,而测试结果显示Bloom Filter不下推到存储引擎时往往会导致性能降低。
+ - 目前Bloom
Filter仅在ScanNode上使用表达式过滤时有短路(short-circuit)逻辑,即当假阳性率过高时,不继续使用Bloom
Filter,但当Bloom Filter下推到存储引擎后没有短路逻辑,所以当过滤率较低时可能导致性能降低。
+- **MinMax Filter**: 包含最大值和最小值,从而过滤小于最小值和大于最大值的数据,MinMax Filter的过滤效果与join on
clause中Key列的类型和左右表数据分布有关。
+ - 当join on
clause中Key列的类型为int/bigint/double等时,极端情况下,如果左右表的最大最小值相同则没有效果,反之右表最大值小于左表最小值,或右表最小值大于左表最大值,则效果最好。
+ - 当join on clause中Key列的类型为varchar等时,应用MinMax Filter往往会导致性能降低。
+- **IN predicate**: 根据join on clause中Key列在右表上的所有值构建IN predicate,使用构建的IN
predicate在左表上过滤,相比loom Filter构建和应用的开销更低,在右表数据量较少时往往性能更高。
+ - 默认只有右表数据行数少于1024才会下推(可通过session变量中的`runtime_filter_max_in_num`调整)。
+ - 目前IN predicate没有实现合并方法,即无法跨Fragment下推,所以目前当需要下推给shuffle
join左表的ScanNode时,如果没有生成Bloom Filter,那么我们会将IN predicate转为Bloom
Filter,用于处理跨Fragment下推,所以即使类型只选择了IN predicate,实际也可能应用了Bloom Filter;
+
+#### 2.runtime_filter_mode
+用于调整Runtime Filter的下推策略,包括LOCAL和GLOBAL两种策略,默认设置为GLOBAL策略。
+
+LOCAL:相对保守,构建的Runtime Filter只能在同一个instance(查询执行的最小单元)上同一个Fragment中使用,即Runtime
Filter生产者(构建Filter的HashJoinNode)和消费者(使用RuntimeFilter的ScanNode)在同一个Fragment,比如broadcast
join的一般场景;
+
+GLOBAL:相对激进,除满足LOCAL策略的场景外,还可以将Runtime
Filter合并后通过网络传输到不同instance上的不同Fragment中使用,比如Runtime
Filter生产者和消费者在不同Fragment,比如shuffle join,这可以在更广泛的场景对查询进行优化。
+
+在不同Fragment上构建和应用Runtime Filter时,需要合并Runtime Filter的原因和策略可参阅 [ISSUE
6116](https://github.com/apache/incubator-doris/issues/6116)
+
+#### 3.runtime_filter_wait_time_ms
+在开启Runtime Filter后,join左表的ScanNode会为每一个分配给自己的Runtime
Filter等待一段时间再扫描数据,默认等待1s(1000ms,以毫秒为单位),即如果ScanNode被分配了3个Runtime
Filter,那么它最多会等待3s。
Review comment:
不是,目前是在一个循环里面,一个一个等待的
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]