时间:2021-04-19来源:www.pcxitongcheng.com作者:电脑系统城
我们都知道数据在缓存中访问远比在磁盘中访问速度要快,那么我们怎么在pg中将指定的数据加载到缓存中呢,这有点类似于Oracle的in-memory。
当然要注意并不是把数据加载到内存中就一定是好的,因为相较于磁盘,内存总是有限的,所以一帮我们只是在特殊场合下将需要的数据加载到内存中来加快访问的速度。
我们可以使用pg_prewarm插件来将指定的表加载到OS Buffer或者pg shared buffer中。
| 1 2  | 
			bill=# create extension pg_prewarm ;CREATE EXTENSION | 
		
构建测试表t1,t2,分别插入1000W条测试数据
| 1 2 3 4 5 6 7 8  | 
			bill=# create table t1(id int,info text);CREATE TABLEbill=# create table t2(id int,info text);CREATE TABLEbill=# insert into t1 select generate_series(1,10000000),md5(random()::text);INSERT 0 10000000bill=# insert into t2 select generate_series(1,10000000),md5(random()::text);INSERT 0 10000000 | 
		
测试前先清空shared_buffer,可以使用下面sql查看shared_buffer使用情况:
安装pg_buffercache插件:
| 1 2  | 
			bill=# create extension pg_buffercache;CREATE EXTENSION | 
		
查询shared_buffer使用情况:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21  | 
			SELECT    c.relname,    count(*) AS buffersFROM pg_buffercache bINNER JOIN pg_class c   ON b.relfilenode = pg_relation_filenode(c.oid)    AND b.reldatabase IN (0, (SELECT oid FROM pg_databaseWHERE datname = current_database()))GROUP BY c.relnameORDER BY 2 DESC;                 relname                 | buffers-----------------------------------------+--------- pg_attribute                            |      36 pg_proc                                 |      27 pg_class                                |      15 pg_operator                             |      14 pg_depend_reference_index               |      13 pg_depend                               |      11 pg_attribute_relid_attnum_index         |      10 pg_proc_proname_args_nsp_index          |       9...... | 
		
可以看到t1和t2表均不在shared_buffer中,我们来手动将t2表加载到shared_buffer中。
| 1 2 3 4 5  | 
			bill=# SELECT pg_prewarm('t2'); pg_prewarm------------      83334(1 row) | 
		
可以看到全表扫描t2表的性能要提升不少。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19  | 
			bill=# explain analyze select * from t1;                                                    QUERY PLAN------------------------------------------------------------------------------------------------------------------ Seq Scan on t1  (cost=0.00..183334.80 rows=10000080 width=37) (actual time=0.060..772.902 rows=10000000 loops=1) Planning Time: 0.294 ms Execution Time: 1044.922 ms(3 rows)Time: 1045.722 ms (00:01.046)bill=# explain analyze select * from t2;                                                    QUERY PLAN------------------------------------------------------------------------------------------------------------------ Seq Scan on t2  (cost=0.00..183334.80 rows=10000080 width=37) (actual time=0.012..519.691 rows=10000000 loops=1) Planning Time: 0.280 ms Execution Time: 790.607 ms(3 rows)Time: 791.314 ms | 
		
下面主要介绍下pg_prewarm函数:
该函式的创建语句如下:
| 1 2 3 4 5 6 7 8  | 
			CREATE FUNCTION pg_prewarm(regclass,mode text default buffer,fork text default main,first_block int8 default null,last_block int8 default null)RETURNS int8AS MODULE_PATHNAME, pg_prewarmLANGUAGE C | 
		
参数如下:
可能有人会想:我直接将表select *全表查询一遍不就可以将数据加载到缓存中了嘛,为什么还需要使用pg_prewarm呢?因为对于大小超过shared_buffer/4的表进行全表扫描时,pg一般不会使用全部的shared_buffer,而是只使用很少一部分的shared_buffer。所以,将大表加载到缓存中不能用一个查询来直接实现的,而pg_prewarm正好可以满足这个需求。
https://www.postgresql.org/docs/13/pgprewarm.html
https://www.postgresql.org/docs/13/pgbuffercache.html
到此这篇关于PostgreSQL将数据加载到buffer cache中的文章就介绍到这了,更多相关PostgreSQL数据加载buffer cache内容请搜索脚本之家以前的文章
2022-09-11
Windows 系统 PostgreSQL 手工安装配置方法教程图解2022-02-25
系统城教小白如何在Centos8-stream安装PostgreSQL132021-04-22
自定义函数实现单词排序并运用于PostgreSQL(实现代码)