CMU15-445/645 SQL层

文章详细阐述了一个SQL语句在数据库中的执行流程,包括Parser构建抽象语法树,Binder绑定实体信息,Planner生成查询计划,Optimizer根据规则优化计划,最后Executors执行计算。同时介绍了Catalog在存储元数据,如表信息和索引信息方面的作用。
摘要由CSDN通过智能技术生成

背景:

一个sql语句进入的执行过程:Parser->Binder->Planner->Optimizer->Executors几个阶段,最后生成一颗executor算子树。各个阶段的功能为:

Parser:根据sql语句生成一颗抽象语法树AST

Binder:根据数据库的元信息,讲抽象语法树转为一个具有库表信息的语义语法树

在得到 AST 后,Binder 将会把这个 AST 改写成 BusTub 可以理解的一个更高级的 AST,如:

Binder 会在 catalog 里面查 __mock_table_1 的信息,将 __mock_table_1 绑定到具体的实体表上 (table_oid=0)。与此同时,将 select * 中的 * 展开成可以查到的所有列。

其中 SELECT 和 FROM 是关键字,* 和 __mock_table_1 是标识符。Binder 遍历 AST,将这些词语绑定到相应的实体上

bustub> explain (binder) select * from __mock_table_1;
=== BINDER ===
BoundSelect {
  table=BoundBaseTableRef { table=__mock_table_1, oid=0 },
  columns=[__mock_table_1.colA, __mock_table_1.colB],
  groupBy=[],
  having=,
  where=,
  limit=,
  offset=,
  order_by=[],
  is_distinct=false,
}

 

Planner:根据语义语法树生成查询计划

物理计划:定义具体的执行方式,例如数据库系统里的算子,hash join,走索引还是走扫描?根据具体数据情况选择具体的物理算子。

Planner 递归遍历 Binder 产生的 BusTub AST,产生一个初步的查询计划,查询计划也是一棵树的形式。在 BusTub 有很多种查询计划(Scan、Join、Projection......),每种查询计划都是这棵树上的一个节点。查询计划规定了数据的流向。数据从树叶流向树根,自底向上地流动,在根节点输出结果。

 

 

Optimizer:根据优化规则,重写等价的查询计划

Optimizer 主要有两种实现方式:

  1. 基于规则(Rule-based):该优化器按照硬编码在数据库中的一系列规则来决定SQL的执行计划,仅是根据预先定义好的规则优化 Plan。例如:谓词下推(Predicate Pushdown)、投影下推(Projection Pushdown)、列裁剪等
  2. 基于代价(Cost-based):估计多个查询计划的代价,进行比较,选择最小的代价。——前提是需要知道数据,知道数据量才知道时间。

bustub是基于规则的优化器,我们将不同的 Rule 按顺序应用到当前的执行计划上,产生最终的执行计划。比如下图利用谓词下推优化执行计划:

注意:在 Optimizer 生成的查询计划中,Join 会被优化成具体的 HashJoin 或 NestedIndexJoin 等。

 

Executors:根据查询计划,生成具体的算子执行树,具体的过程是,遍历查询计划树,将树上的 Plan 替换成对应的 Executor

我们通过火山模型执行算子,从叶子节点开始向上层算子吐自己的数据,直到顶层。

其中Executors是本节我们需要实现的对象

整体的示意图:

 

Catalog的介绍:

catalog在这一节中被广泛用到,我们必须要对它了解才能完成lab。

DBMS讲数据库的元数据存储在catalog中,如表名,索引,试图,用户权限等。一个数据库维护了内部的catalog来回答当前有哪些表存在,表中每一列的类型,位置在哪等等。

Schema

 可以简单理解为对于字段和列的描述信息。如描述这个表中有哪些列,每个列的类型是什么。

对于一个tuple,每张表中的每一行数据是value+schema组成的。schema指明了tuple中value部分存储的是什么类型的数据,如value是100,schema指出是100元还是100米还是100分。

TableInfo

struct TableInfo {
  /** The table schema */
  Schema schema_;
  /** The table name */
  const std::string name_;
  /** An owning pointer to the table heap */
  std::unique_ptr<TableHeap> table_;
  /** The table OID */
  const table_oid_t oid_;
};

 TableInfo 维护的是一张表的所有元数据(Metadata),比如一张表的 schema,表的名称,表的唯一标识 id,以及指向 table heap 的指针。

table heap 本身并不直接存储 tuple 数据,tuple 数据都存放在 table page 中。table heap 可能由多个 table page 组成,仅保存其第一个 table page 的 page id。需要访问某个 table page 时,通过 page id 经由 buffer pool 访问。

 

 IndexInfo

struct IndexInfo {
  /** The schema for the index key */
  Schema key_schema_;
  /** The name of the index */
  std::string name_;
  /** An owning pointer to the index */
  std::unique_ptr<Index> index_;
  /** The unique OID for the index */
  index_oid_t index_oid_;
  /** The name of the table on which the index is created */
  std::string table_name_;
  /** The size of the index key, in bytes */
  const size_t key_size_;
};

 类似的IndexInfo 维护的是一个索引表的所有元数据(Metadata),比如该索引 key 所在表的名称,索引名称、索引唯一表示 id 等信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值