对于扫表的查询,buffer区该如何应对?
1.如果没有额外的处理会如何
例如扫描表tableA
select * from tableA;
当tableA有许多页面,查询会将tableA的页面加载到buffer区中,那么就会将buffer区大量甚至全部的页面淘汰了。这个就不是我们希望看到的,前面我们按照 clock sweep的NFU算法,将频繁访问的页面留在内存中,然后一次扫表查询,就把buffer高频访问的页面淘汰,相当不划算。
2.解决方式
对于扫表的查询,限定查询使用的buffer数量。例如一次扫表查询,限定使用20个buffer,后续加载第21个页面时,也在这20个buffer进行淘汰。
在PG代码中,提出了ring buffer,
除了扫表查询(Bulk-READ),还有批量写(Bulk-writing)、vacumm机制需要ring buffer
3.具体实现
在PG中,获取buffer,分成两种有策略情况和普通情况
有策略情况,对应这对于扫表查询、批量写这样的情况,需要分配一个ring buffer,buffer的分配需要在ring buffer内进行分配。(可能这叫策略吧)
普通情况就是正常的随机访问,buffer的分配就是在buffer池进行分配
typedef enum BufferAccessStrategyType { BAS_NORMAL, /* Normal random access *