Loading

2023Spring project3

Task1:Access Method Executors

第一个task就是完成access method相关的算子,有:

  • seqscan
  • insert
  • update
  • delete
  • index_scan

Seqscan

seqscan属于最底层的算子,所以它没有子算子了,它需要做的就是从Table中读取tuple。

在Init阶段,我们应该通过exec_ctx_去获得这个算子对应的table,从而得到这个table对应的迭代器。
在Next阶段,逻辑非常简单,每调用一次Next,就会得到一次迭代器对应的数据,同时让迭代器自增,直到迭代器到达了终点。

Insert

Insert需要在Init阶段,调用子算子的Init。根据要求,Insert需要一次性把子算子的所有tuple全部插入到表中才算完成,所有我们要循环调用子算子的Next,直到子算子返回false为止。
把这个过程中产生的tuple全部插入到table中,同时我们也要更新table上对应的所有索引,把这个tuple也插入到索引中去。
只需要把tuple中对应的索引字段插入到索引中去即可,tuple和index有对应的API可以调用。

Delete

Delete与Insert大致相同,我们需要找到子算子产生的所有tuple,在表中对应的位置。然后修改表,将这个tuple的元信息置为已删除。
之后还要调用与这个表相关的所有索引,在索引中也删除对应的tuple。

Update

这个算子基于Insert和Delete,把tuple先删除,然后再将更新之后的tuple作为一个新的tuple插入到表中去。

Index_scan

这里的index就是P2我们完成的B+树,我们需要先获取B+树对应的迭代器。获取到迭代器之后,剩下的工作和seqscan是一样的。

Task2:Aggregation & Join Executors

这个task里需要完成聚合算子和连接算子。

Aggregation

头文件里提供给了我们一个简单的哈希表,我们将要利用这个哈希表来做聚合操作,所以先得补全哈希表里的函数CombineAggregateValues。
这个函数的功能就是遍历agg_exprs,根据expr中给出的每一列的类型,比如说这一列要求计算COUNT(*),那我们就无条件让result对应列加一。如果是计算Sum,那么我们就将result对应列的值和input对应列的值相加即可。

比如说SELECT SUM(colA) FROM test GROUP BY colB;
colB就是我们的agg_key,此时表中colB的值有多少个,我们的哈希表就有多少个key,因为我们会拿agg_key作为哈希表的key。同时遍历表中所有的colA,把他的值加到对应的哈希表中的项中,从而达到了分组计算的效果。

在aggregation算子部分,Init阶段需要得到子算子所有的tuple,并且提取出其中相对应的agg_key和agg_value部分,插入到哈希表里,然后初始化哈希表迭代器。
在Next部分,只需要取出迭代器中的一项,迭代器里存储了agg_key和agg_value,我们将两者组合后,构造出一个tuple返回即可。

Join

2023 Spring需要实现的是简单Hash Join,不需要实现Grace Join,我们可以假设哈希表能全部放在内存中。

这个算子有两个子算子,分别对应着左表的tuple与右表的tuple。
在我的实现中,我会统一将右表所有的tuple放到哈希表里,这一步在Init完成。
在Next中,我们需要遍历左表的所有tuple,对于每一个tuple来说,需要遍历整个其对应的哈希表里的所有右表tuple,如果能join,那么产生一个新tuple然后返回true。
在下一次调用Next时,我们要从上一次Next结束的位置,继续遍历,因为一个左表tuple是可能和多个右表tuple join的。如果一个左表tuple没有和任何右表tuple join过,那么我们需要检查是否为左连接,如果是左连接,我们需要构造一个空右表tuple来和左表tuple连接。

然后我们需要修改一下优化器里的规则,让NLJ能被优化器优化成我们实现的Hash Join。

Task3:Sort + Limit Executors and Top-N Optimization

这一步需要实现Sort和Limit两个算子,然后完成一个TOP-N的查询优化。

Sort

Sort比较简单,在Init里我们需要提取出order_bys,这里面就是排序关键字。我们依照从左往右优先级逐次下降的方式,构造一个比较函数,然后调用std::sort进行排序就行了。

Limit

这个算子更简单了,我们只需要限制调用Next的次数即可。

Top-N

Top-N优化指的是,某一个查询使用了ORDER BY与LIMIT,这等价于求表中前N项。
所以可以不必对全表排序,而是利用部分排序算法,或者构造一个堆,注意C++中的堆默认实现是大根堆,因此需要倒序输出。

最后,我们需要修改一下查询器里的规则,让Top-N算子能正式生效。

image

posted @ 2023-09-14 20:58  烤肉kr  阅读(4)  评论(0编辑  收藏  举报