查询优化器(RBO) | 青训营笔记

这是我参与「第四届青训营 」笔记创作活动的的第2天

常见的查询优化器

查询优化器的分类(两种分类方法)

  • Top-down Optimizer

    • 从目标输出开始,由上往下遍历计划树,找到完整的最优执行计划
    • 例子: Volcano/Cascade,SQLServer
  • Bottom-up Optimizer

    • 从零开始,由下往上遍历计划树,找到完整的执行计划
    • 例子: System R,PostgreSQL,IBM DB2
  • Rule-based Optimizer (RBO)

    • 根据关系代数等价语义,重写查询
    • 基于启发式规则
    • 会访问表的元信息(catalog),不会涉及具体的表数据(data)
  • Cost-based Optimizer (CBO)

    • 使用一个模型估算执行计划的代价,选择代价最小的执行计划

RBO (Rule-based Optimizer)

关系代数

即基于关系代数的等价变换

运算符:

等价变换:结合律,交换律,传递性

  • image-20220725150117488
  • image-20220725150846999
  • image-20220725150902238

优化原则

Read data less and faster (I/o) Transfer data less and faster (Network) Process data less and faster (CPU & Memory)

目的是一个查询跑得快,因此需要一些优化的目标。整体上可以分为三点,可以优化它的I/O,(希望读更少数据,读数据的时候更快)、优化网络,(希望传输的数据更少,传输数据也更快)、优化它的cpu和内存,(希望处理数据的时候,cpu的指指定数更少,内存使用更少,重叠数据更少)

image-20220725152205517

优化逻辑计划。

列裁剪

image-20220725160214588

image-20220725154715577

基本思想:

对于一个查询,相对应的算子实际上用不到列,那么在进行计算的时候是不需要去读取去保留它们,因此尽早的这些列去掉,减少一些I/O或者是内存的占用,然后为后续的优化带来便利。

这个优化从上了往下扫描,计算算子需要哪些列,继而传递FILTER,再加上FILTER自己需要的列,再和上层传递下来的列组成一个新的集合,继而继续往下传递。

谓词下推

image-20220725160451597

在上述条件里面的表达式就称为谓词。在一个需要过滤数据的查询,需要在更早的形面过滤,或者说在更后面过滤它,在某些场景下它的结果是不受影响,都是正确的,因此希望把这个位置尽可能下推,尽早的过滤数据,过滤掉一些不必要的数据,不必要的函数有效的减少传输或者计算的开销。 image-20220725160511490

传递闭包

image-20220725161114139

基本思想:根据一些等价关系再加上一些过滤条件,可以推导出一个新的过滤条件。

结构图:image-20220725161752456

举例解释: 传递闭包——从左边到右边的转化

实则左边是经过列裁结,经过谓词下推之后的一个执行计划

右边可以推导出一个新的FILTER——可以把pv的SCAN往下推,推过这个JOIN就得到了右边一个执行计划

继而把现有的FILTER往下推,同时产生了一个新的FILTER,JOIN的两边其实都经过了FILTER的过滤,数据量会减少很多,那么做连接操作的时候会很快。

Runtime Filter

即这是一个运行时的FILTER,只有在运行时才能产生FILTER。广泛运用在数据库中。

image-20220726094307242

原理:对于单个JOIN,希望在PO(即查询端)去查询表里面数据是不是存在的思想。可以提早过滤左边的数据,可以去进行预算,,减少许多不必要的数据,减少开销

比如JOIN是通过一个哈希表来实现,右端是已经构建好的哈希表应用,左边是一个遍历关系。哈希表需要计算哈希Code,同时还有比较操作。

核心思想——Runtime Filter能不能产生新的FILTER,下推到JOIN的查询端。

小结

  • 主流RBO实现一般都有几百条基于经验归纳得到的优化规则

  • 优点:实现简单,优化速度快

  • 缺点:不保证得到最优的执行计划

    • 单表扫描:索引扫描(随机I/O) vs.全表扫描(顺序I/O)

      • 如果查询的数据分布非常不均衡,索引扫描可能不如全表扫描
    • Join的实现:Hash Join vs. SortMerge Join

    • 两表Hash Join:用小表构建哈希表——如何识别小表?(做不到)

    • 多表Join:

      • 哪种连接顺序是最优的?

      • 是否要对每种组合都探索?

        • N个表连接,仅仅是left-deep tree就有差不多N!种连接顺序
        • e.g. N= 10->总共3,628,800个连接顺序
  • image-20220726095726741

posted @ 2022-07-26 14:02  Luciferpluto  阅读(0)  评论(0)    收藏  举报  来源