首页 > 其他分享 >Databend join reorder 策略

Databend join reorder 策略

时间:2023-10-11 11:46:19浏览次数:46  
标签:join csg tree 枚举 Databend 算法 reorder cmp

join order 的重要性

Join order 是指在执行SQL查询时,决定多个表进行 join 的顺序。它是数据库查询优化的一个重要方面,对查询性能和效率有着重要的影响, 不同的 join order 对性能可能有数量级的影响。

优化器优化 join order 的核心流程

  1. join plan 枚举
  2. 根据统计信息估算结果的大小 (cardinality estimation)
  3. 把 2 中的结果带入到代价模型计算枚举 plan 的 代价 (cost model)

本文中我们只关心第一步 join plan enumeration, 也就是 join reorder 算法。

join reorder 算法

贪心启发式算法

当需要 join 的表都数量过多时(通常超过10个),适合用贪心算法,其优势在于能够较快的找到还不错的 join order.

核心思想:从一张表拓展到 N 张表,每次选出使当前代价最小的一张表,加入到 join tree中,构建出 left-deep tree.

贪心算法也有很多拓展,主要拓展点是围绕如果 避免局部最优以及产生 bushy tree

枚举算法(top-down & bottom-up)

主流的两种

  • 基于规则变换的 Top-down 枚举,可以结合 Top-down cascasde 框架通过记忆化的方式来实现
  • 基于 DP 的 bottom-up 枚举, 典型代表 DPhyp 算法,其优势在于可以高效的产生 bushy tree

一般情况下,数据库系统会把贪心和枚举有效的结合,从而对任意数量的表 join 都能够在合理的时间内得到有效的 join order

Databend join reorder 现状

databend 优化器基于 Rule 进行优化,每条 Rule 通过 pattern 来匹配 plan 中的 sub-tree。主要分为两个阶段,启发式优化和基于 cascades 框架的代价优化,两个阶段共用一套 Rule。

在启发式阶段优化结束后,会对优化后的 plan 执行 DPhyp 算法来尝试得到最优的 join order, 如果 Dphyp 优化失败,会在 CBO 中找到最优的 left-deep tree. (CBO 中不尝试进行 bushy tree 优化,因为如果 Dphyp 已经优化失败,那么尝试在 CBO 中进行 bushy tree 优化,搜索空间很有可能爆炸,如 tpcds 64)

Databend 目前没有支持贪心算法 (下一阶段的 roadmap 会做相关支持来处理极端情况下的 case),首先会利用 dphyp 算法来得到最优解,如果 dphyp 失败(query 中存在不适合 dphyper 算法的 pattern),会在 cascades 框架中利用基于规则变换的 Top-down 枚举得到 left-deep tree. 如果表的数量过多,如超过十个,会在 dphyp 算法中放弃部分搜索空间来做 tradeoff。

Dphyp 的核心定义及算法

hypergraph

一个超图是一个由节点集合 V 和超边集合 E 组成的二元组 H = (V,E),其中:

  1. V是非空节点集合。
  2. E是超边集合,超边是V的非空子集(u ⊂ V)和(v ⊂ V)的无序对(u,v),并且满足额外条件 u∩v = ∅。

有了超图就可以描述多节点之间连接。

对于上图,它们的 join condition 是 R1.a + R2.b + R3.c = R4.d + R5.e + R6.f 所以 hyperedge 就是 {R1, R2, R3} — {R4, R5, R6}

csg-cmp-pair

csg: connected-subgraph (连通子图)

cmp: connected-complement (连通互补对)

如果两个 csg 之间没有交集,且存在超边连接,其中一个就是另一个的 cmp, 二者构成 csg-cmp-pair. 算法的核心就是通过递归无重复的枚举出所有的 csg-cmp-pair, 找出代价最小的包含所有点的 csg-cmp-pair.

algorithm

算法核心:hypergraph 中的节点是有序的,节点从后往前迭代(递减),每个节点只考虑其自身及其之后(序列号更大)的节点,找到可能的连通子图及其连通互补图,构成 csg-cmp-pair, 计算并更新出其代价,当迭代到最小的节点后,会得到包含所有点的 csg-cmp-pair, 算法结束。

算法流程

  1. EmitCsg: 寻找 {v} 的互补连通子图
    • a. 如果找到, EmitCsgCmp
    • b. EnumerateCmpRec:扩展互补连通子图
      • 如果扩展后的互补连通子图可以与 {v} 形成 csg-cmp-pair, 则 EmitCsgCmp
      • 回到 b,继续扩展
  2. EnumerateCsgRec: 扩展
    • a. 得到扩展后的 {v’}, 对 {v’} 执行 1
    • b. 回到2,继续扩展

核心代码和数据结构定义可参考:

(https://github.com/datafuselabs/databend/blob/main/src/query/sql/src/planner/optimizer/hyper_dp/dphyp.rs)

Connect With Us

Databend 是一款开源、弹性、低成本,基于对象存储也可以做实时分析的新式数仓。期待您的关注,一起探索云原生数仓解决方案,打造新一代开源 Data Cloud。

标签:join,csg,tree,枚举,Databend,算法,reorder,cmp
From: https://www.cnblogs.com/databend/p/17756697.html

相关文章

  • 表和数据连接,而不是和表连接(JOIN)
    1、连接数据,但是顺序会受影响在使用JOIN连接临时表或子查询时,无法保证结果的顺序与特定值的顺序完全一致。这是因为在查询过程中,数据库优化器可能会选择不同的执行计划,导致结果的顺序发生变化。SELECTTABLE_NAME.*FROMTABLE_NAMEJOIN(SELECT'AA'ASIDU......
  • Mysql join算法深入浅出
    导语联表查询在日常的数据库设计中非常的常见,但是联表查询可能会带来性能问题,为了调优、避免设计出有性能问题的SQL,在explain命令中,会显示用的是哪个join算法,学习一下join过程是非常有必要的当执行下面这个SQLJoin,在不同的情况下会产生不一样的复杂度select*fromusertb1l......
  • python queue join task_done的概念及实例解析
    一概念Queue.task_done()在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号Queue.join()实际上意味着等到队列为空,再执行别的操作。 二实例源码一importthreadingimportqueueimporttime#创建队列,用于存储数据q=queue.Qu......
  • ClickHouse选择正确的join算法
    支持的JOIN类型 JOIN算法概览clickhouse提供了6种JOIN算法:1.直接连接(Directjoin)2.哈希连接(Hashjoin)3.并行哈希连接(Parallelhashjoin)4.优雅哈希连接(Gracehashjoin)5.全排序合并连接(Fullsortingmergejoin)6.部分合并连接(Partialmergejoin) 这......
  • 前端​​join()​​函数
    在前端开发中,join()函数是用于数组的一个方法。它将数组中的所有元素按照指定的分隔符连接起来,并返回一个字符串。该函数的语法如下:array.join(separator)其中,array是要被连接的数组,separator是数组元素之间的分隔符。分隔符可以是一个字符串,用于在每个数组元素之间进行分隔。如果......
  • 包装类、StringBuilder、StringBuffer、StringJoiner
    1、怎么将Int类型的包装成对象使用Integer的valueOf方法Integera2==Integer.valueOf(12);2、自动装箱机制(可以自动把基本数据类型的数据转换成对象)Integera3=12;自动拆箱机制(可以自动把包装类型的对象转换成对应的基本数据类型)inta4=a3;......
  • delete 和 join 理解使用
    delete和join先来两个语句:DELETEstudentgradeFROMcourseWHEREcourse.course_name='数据结构'andstudentgrade.course_id=course.course_idDELETEstudentgradeFROMcoursejoinStudentGradeonstudentgrade.course_id=course.course_idWHEREcourse.course_......
  • Kubernetes 无法join:[ERROR CRI]: container runtime is not running:
    Kubernetes初始化成功,然后将node加入,结果报错:[root@k8s-node1~]#kubeadmjoin10.10.10.185:6443--token84pas2.ifxb6o8g7h2abg28--discovery-token-ca-cert-hashsha256:f85f0c324e0b951238617f9037832b63e4c4a6c7679aaa53c711a829fc9374e6[preflight]Runningpre-flight......
  • Kubernetes 无法join:[ERROR CRI]: container runtime is not running:
    Kubernetes初始化成功,然后将node加入,结果报错:[root@k8s-node1~]#kubeadmjoin10.10.10.185:6443--token84pas2.ifxb6o8g7h2abg28--discovery-token-ca-cert-hashsha256:f85f0c324e0b951238617f9037832b63e4c4a6c7679aaa53c711a829fc9374e6[preflight]Runningpre-flight......
  • 27、Flink 的SQL之SELECT (Group Aggregation分组聚合、Over Aggregation Over聚合 和
    文章目录Flink系列文章一、GroupAggregation分组聚合1、count示例2、groupby的聚合示例3、distinct聚合4、GROUPINGSETS1)、ROLLUP2)、CUBE5、Having二、OverAggregation1、语法1)、ORDERBY2)、PARTITIONBY3)、RangeDefinitions4)、RANGEintervals5)、ROWintervals2、示例三、......