使用pg_prewarm缓存PostgreSQL数据库表

pg_prewarm

pg_prewarm 直接利用系统缓存的代码,对操作系统发出异步prefetch请求,在应用中,尤其在OLAP的情况下,对于大表的分析等等是非常耗费查询的时间的,而即使我们使用select table的方式,这张表也并不可能将所有的数据都装载到内存中,而pg_prewarm的功能就是完成一个张表全部进入到内存中的功能。

按照官方文档 PostgreSQL 13的说明,预热有两种方式,一种是手动调用pg_prewarm函数,用于将当前所需的数据装入内存。另一个选择是自动执行,要要设置shared_preload_libraries参数。设置完毕后,系统将自动运行一个后台工作进程,它定期将shared_buffer中的内容写入到文件 autoprewarm. blocks中,以便在重新启动数据库后,快速加载该文件内部的数据块,实现预热功能。

安装与使用方式

sql 复制代码
create extension pg_prewarm;
-- t1为表名
SELECT pg_prewarm('t1');

参数

函数体为

sql 复制代码
CREATE FUNCTION pg_prewarm(regclass,
mode text default buffer,
fork text default main,
first_block int8 default null,
last_block int8 default null)
RETURNS int8
AS MODULE_PATHNAME, pg_prewarm
LANGUAGE C
  • regclass:要做prewarm的表名
  • mode:prewarm模式。prefetch表示异步预取到os cache;read表示同步预取;buffer表示同步读入PG的shared buffer
  • fork:relation fork的类型。一般用main,其他类型有visibilitymap和fsm
  • first_block & last_block:开始和结束块号。表的first_block=0,last_block可通过pg_class的relpages字段获得
  • RETURNS int8:函数返回pg_prewarm处理的block数目(整型)

因为对于大小超过shared_buffer/4的表进行全表扫描时,pg一般不会使用全部的shared_buffer,而是只使用很少一部分的shared_buffer。所以,将大表加载到缓存中不能用一个查询来直接实现的,而pg_prewarm正好可以满足这个需求。

性能测试

在一个3363786记录数的业务表中,添加缓存之前的

sql 复制代码
explain (analyze,buffers) select *  from t1;

添加缓存后

sql 复制代码
create extension pg_prewarm
SELECT pg_prewarm('t1');
explain (analyze,buffers) select *  from t1;

对比上面2图,可以看出,时间大幅度下降.

相关推荐
AAA修煤气灶刘哥15 小时前
数据库优化自救指南:从SQL祖传代码到分库分表的骚操作
数据库·后端·mysql
老纪的技术唠嗑局20 小时前
经验分享 —— 在 Ubuntu 虚拟机中部署 OceanBase 数据库
数据库·ubuntu
咖啡Beans21 小时前
MySQL中使用@符号定义用户变量
数据库·mysql
GreatSQL1 天前
MySQL迁移至GreatSQL后,timestamp字段插入报错解析
数据库
expect7g1 天前
COW、MOR、MOW
大数据·数据库·后端
DemonAvenger1 天前
MySQL海量数据快速导入导出技巧:从实战到优化
数据库·mysql·性能优化
薛定谔的算法2 天前
phoneGPT:构建专业领域的检索增强型智能问答系统
前端·数据库·后端
Databend2 天前
Databend 亮相 RustChinaConf 2025,分享基于 Rust 构建商业化数仓平台的探索
数据库
得物技术2 天前
破解gh-ost变更导致MySQL表膨胀之谜|得物技术
数据库·后端·mysql
Raymond运维2 天前
MariaDB源码编译安装(二)
运维·数据库·mariadb