PgSQL内核代码阅读|查询的两种实现方式

PgSQL内核代码阅读|查询的两种实现方式

PgSQL查询用户表时,针对带有WHERE条件的顺序扫描查询,他会从存储加载数据,然后一条一条的从页中读取数据,并将其返回给SeqScan算子。在SeqScan算子中处理WHERE过滤,即ExecQual函数处理过滤表达式。对于系统表还有另一种查询方式,即使不经过索引,也可以通过ScanKeyInit将过滤条件值带入ScanKeyData中,从而在存储层就将值过滤掉,仅向SeqScan算子推送满足条件的元组。下面我们分别看下这两种方式。

1、针对用户表

PgSQL内核代码阅读|查询的两种实现方式_第1张图片

如上图所示,对于普通的顺序扫描,直接在存储引擎层也就是heap表访问方法层:从第1页开始加载,并且从第一页的第一个元组开始推送到SeqScan算子,在SeqScan算子中调用ExecScan函数拉取存储引擎的元组,并通过ExecQual进行过滤表达式计算,将不满足条件的值丢掉,继续拉取下一条元组;将满足条件的元组继续向上层算子推送,或者无父算子时,直接向客服端发送。

2、针对系统表

还有另一种扫描方式,虽然也是顺序扫描,但是不经过SeqScan算子,他是内核内部扫描系统表的一种方式,他将过滤下推到了存储引擎层,在表访问方法处完成过滤,仅将满足条件的元组输出。我们以给定扩展名查找他的OID为例看下他的处理流程:

PgSQL内核代码阅读|查询的两种实现方式_第2张图片

他的过滤放在了heapgettup函数中,即通过HeapKeyTest进行key值比较,满足条件时将valid标记为true。

你可能感兴趣的:(PgSQL内核代码阅读|查询的两种实现方式)