1.常用内存参数

1.1 shared_buffers

shared_buffers是PostgreSQL用于共享缓冲区的内存,是由8kb大小的块所形成的数组。PostgreSQL在进行更新、查询等操作时,首先从磁盘把数据读取到内存,之后进行更新,最后将数据写回磁盘。shared_buffers可以暂时存放从磁盘读取的数据,能够让用户下次访问不需要去磁盘直接从里面读取出来,增加查询效率。shared_buffers的系统默认值通常为128MB。但是当PostgreSQL服务器的内存大于1G时,则shared_buffers的合理起始值为系统内存的25%,如果由于业务原因可以将shared_buffers设置的更大,但是PostgreSQL依赖于操作系统的缓存,因此建议分配不要超过系统内存的40%。建议设置系统内存的25%-40%。

在PostgreSQL中,shared_buffers可以通过explain (analyze,buffers)来查看出多少数据块来源磁盘,多少来源shared_buffers,即内存的。

测试语句:


  1. EXPLAIN (ANALYZE,BUFFERS) SELECT * FROM viid_vehicle.vehiclestructured
  2. WHERE recordid=1220098697128879629;
  3. --运行结果
  4. Index Scan using idx_vehiclestructured_recordid on vehiclestructured  (cost=0.43..8.45 rows=1 width=167)
  5. (actual time=61.687..61.689 rows=1 loops=1)
  6.    Index Cond: (recordid = '1220098697128879629'::bigint)
  7.    Buffers: shared read=4
  8.  Planning time: 295.504 ms
  9.  Execution time: 62.220 ms

再次运行同样的查询计划,运行结果:


  1. Index Scan using idx_vehiclestructured_recordid on vehiclestructured (cost=0.43..8.45 rows=1 width=167)
  2. (actual time=0.018..0.019 rows=1 loops=1)
  3.    Index Cond: (recordid = '1220098697128879629'::bigint)
  4.    Buffers: shared hit=4
  5.  Planning time: 0.090 ms
  6.  Execution time: 0.063 ms

shared read(共享读取)指的是其取自磁盘且不被缓存。再次执行该查询计划后,结果以shared hit的形式展现,hit就是读取shared_buffers的。

1.2 work_mem

work_mem是PostgreSQL在写入临时磁盘文件之前,进行内部sort(order by)和hash(join)操作需要使用的内存量。work_mem需要通过explain analyze分析语句来确定合适的值。

例子:先设置work_mem为1MB。

SET work_mem='1MB';

测试语句:


  1. EXPLAIN ANALYZE SELECT * FROM viid_vehicle.vehiclestructured_test WHERE plateno = '浙G98948' ORDER BY vehiclebrand;
  2. --运行结果
  3. Sort  (cost=162.14..162.23 rows=39 width=167) (actual time=310.765..310.772 rows=38 loops=1)
  4.    Sort Key: vehiclebrand
  5.    Sort Method: quicksort  Memory: 35kB
  6.    ->  Index Scan using idx_vehiclestructured_test_plateno on vehiclestructured_test  (cost=0.43..161.11 rows=39 width=167) (actual time=41.104..310.648 rows=38 loops=1)
  7.          Index Cond: ((plateno)::text = '浙G98948'::text)
  8.  Planning time: 194.344 ms
  9.  Execution time: 310.828 ms

看到当前的Sort Method为quicksort(快速排序),对38行数据进行排序,PostgreSQL使用了35kb内存,接下来增大排序的数据量:

测试语句:


  1. EXPLAIN ANALYZE SELECT * FROM viid_vehicle.vehiclestructured_test WHERE plateno LIKE '%S906%' ORDER BY vehiclebrand;
  2. --运行结果
  3.  Sort  (cost=3919.22..3921.70 rows=991 width=167) (actual time=134.259..135.692 rows=3863 loops=1)
  4.    Sort Key: vehiclebrand
  5.    Sort Method: external merge  Disk: 720kB
  6.    ->  Bitmap Heap Scan on vehiclestructured_test  (cost=79.68..3869.90 rows=991 width=167) (actual time=105.735..129.871 rows=3863 loops=1)
  7.          Recheck Cond: ((plateno)::text ~~ '%S906%'::text)
  8.          Rows Removed by Index Recheck: 30
  9.          Heap Blocks: exact=3867
  10.          ->  Bitmap Index Scan on idx_vehiclestructured_test_plateno_like  (cost=0.00..79.43 rows=991 width=0) (actual time=105.213..105.213 rows=3893 loops=1)
  11.                Index Cond: ((plateno)::text ~~ '%S906%'::text)
  12.  Planning time: 471.028 ms
  13.  Execution time: 136.904 ms

根据上面可以看出来,当排序的数据量达到3893行时,Sort Method由使用内存排序到需要借助临时磁盘文件720kb,说明work_mem设置的值已经被占满了。

将work_mem的值增加到2MB。

 SET work_mem='2MB';

  1. --运行结果
  2.   Sort  (cost=3919.22..3921.70 rows=991 width=167) (actual time=136.279..137.135 rows=3863 loops=1)
  3.    Sort Key: vehiclebrand
  4.    Sort Method: quicksort  Memory: 1123kB
  5.    ->  Bitmap Heap Scan on vehiclestructured_test  (cost=79.68..3869.90 rows=991 width=167) (actual time=113.936..134.132 rows=3863 loops=1)
  6.          Recheck Cond: ((plateno)::text ~~ '%S906%'::text)
  7.          Rows Removed by Index Recheck: 30
  8.          Heap Blocks: exact=3867
  9.          ->  Bitmap Index Scan on idx_vehiclestructured_test_plateno_like  (cost=0.00..79.43 rows=991 width=0) (actual time=113.368..113.368 rows=3893 loops=1)
  10.                Index Cond: ((plateno)::text ~~ '%S906%'::text)
  11.  Planning time: 636.118 ms
  12.  Execution time: 38.633 ms

可以看到当设置的work_mem到2MB时,3863行数据的排序全会在内存中进行,使用了1123kb,同时执行时间从原来136ms到38ms。

实际生产环境中, work_mem值需要经过多次测试才能设定比较合理合适的值。需要注意的是work_mem是每单个连接用户使用的内存,也就是实际需要的内存为max_connections * work_mem,必须保证max_connections*work_mem的值不要超过实际可用的内存。

1.3 maintenance_work_mem

maintenance_work_mem定义的内存主要影响vacuum,analyze,create index,reindex等操作,这些命令用到的频率不高,但是会消耗较多的资源,系统默认值通常为64MB,可以分配高一点的内存,让上述命令进行地快速一点。当系统内存为32G时,可以分配512MB-1024MB的内存。

1.3.1 vacuum

上面提到了vacuum,在这里详细解释一下,在PostgreSQL中vacuum是一个非常重要的命令。数据库数据在不断地执行更新,删除等操作,而vacuum就是用来维护数据库磁盘空间。

在PostgreSQL中实际上执行了delete操作后,该记录只是被标示为删除状态,并没有释放其空间,在以后进行insert和update操作时,该删除状态的空间是不能够被重用的。只有经过vacuum清理后,空间才能真正得到释放。总结一下,vacuum有以下三个功能:

(1). 释放delete操作后的空间,并且再利用。

(2). 更新PostgreSQL查询计划用得统计数据。

(3). 避免事务ID的重置而引起非常老的数据丢失。

执行vacuum有手动和自动两种形式:1.自动vacuum的执行由autovacuum参数值决定,默认值为on,autovacuum还有很多相关的参数。2.手动执行vacuum一般是在每天数据库空闲的时候进行,因为执行vacuum的时候,有大量的I/O操作,会导致其他的操作性能降低。

1.4 effective_cache_size

effective_cache_size是优化器假设查询可以使用的最大内存(包括PostgreSQL和系统缓存),和shared_buffer内存无关,只是给优化器生产计划使用的一个假设值。该值建议设置为可用空闲内存的25%-50%,设置值大点,可以让优化器更倾向使用索引扫描而不是顺序扫描。

1.5 wal_buffers

wal_buffers是用于还没写入磁盘的WAL(预写入日志)数据的共享内存量,主要影响数据库的写入性能。该参数的默认值为-1,PostgreSQL会自动选择一个合理的值。但是一般情况给的值都不超过1MB,wal_buffers的内容是在每次事务提交时写入磁盘,因此设置太大的值也没有用处。但是根据官网原话,将此值设置为至少几兆可以提高许多客户端一次提交的写入性能。

2.内存和OS缓存

PostgreSQL是一个跨平台数据库,其缓存很大程度上依赖于操作系统。而shared_buffers共享缓存其实就是在复制OS缓存的操作,下图1为数据在PostgreSQL内部的流向图

图1 数据在PostgreSQL内部的流向图

先来简单说明一下数据库的读和写:数据从磁盘流入内存叫读;数据从内存流入磁盘叫做写。在PostgreSQL中数据从磁盘到OS存储器再到shared_buffers的过程叫做读。针对这个现象,平时OS缓存有很大一部分是处于空闲状态或者是用得并不频繁,因此根据自身的生产环境需求可以合理来配置shared_buffers和OS缓存。

3.手动加载内存

pgfincore是一个PostgreSQL的外部扩展,能够将数据库中的表或索引手动提前加载到OS cache中,是数据预加载的一种,能够加快查询效率,但是加载到缓存中也不是永久的,当有频繁的缓存交换时,比如批量的最大限度的插入数据,会把加载的数据挤出去。

3.1 pgfincore安装

在pgfoundry(搜索软件搜即可)或者

https://gitee.com/mirrors/PgFincore?utm_source=alading&utm_campaign=repo

上下载pgfincore的安装包,将其解压到PostgreSQL源码目录的contrib下:


  1. tar  –zxvf  pgfincore-v1.1.1.tar.gz
  2. cd  pgfincore-1.1.1
  3. make
  4. make install

安装好了之后切换postgres用户进入psql


  1. su postgres
  2. psql

创建扩展pgfincore(注意,需要在使用的库名下创建才可以使用):


  1. CREATE EXTENSION pgfincore;
  2. --查看是否创建成功:
  3. SELECT * FROM pg_extension;
  4. --结果
  5. extname |  extowner | extnamespace | extrelocatable | extversion | extconfig | extcondition
  6. plpgsql   |       10 |           11 | f              | 1.0        |       
  7. pgfincore |       10 |         2200 | t              | 1.1.1      |     

3.2 pgfincore常用方法

pgfincore() 对象的cache情况

pgfadvise_willneed() 将对象手动刷入cache

pgfadvise_dontneed() 将对象手动刷出cache

pgsysconf() 操作系统的cache情况

pgsysconf_pretty() 同上,只不过输出更易懂,戴上了单位


  1. SELECT * FROM pgsysconf_pretty();
  2.     os_page_size | os_pages_free | os_total_pages
  3. -------------+--------------+----------------
  4.     4096 bytes    | 118 MB          | 32 GB

3.3 pgfincore性能测试

(1). 测试没有将表添加到内存中

测试语句:


  1. EXPLAIN ANALYZE SELECT * FROM viid_vehicle.vehiclestructured WHERE plateno LIKE '%S906%';
  2. --运行结果
  3. Bitmap Heap Scan on vehiclestructured  (cost=83.84..1982.68 rows=496 width=167) (actual time=117.193..6559.904 rows=1913 loops=1)
  4.    Recheck Cond: ((plateno)::text ~~ '%S906%'::text)
  5.    Rows Removed by Index Recheck: 14
  6.    Heap Blocks: exact=1908
  7.    ->  Bitmap Index Scan on idx_vehiclestructured_plateno_like  (cost=0.00..83.72 rows=496 width=0) (actual time=74.204..74.205 rows=1927 loops=1)
  8.          Index Cond: ((plateno)::text ~~ '%S906%'::text)
  9.  Planning time: 260.415 ms
  10.  Execution time: 6561.209 ms

(2). 测试将表添加到内存中

测试语句:


  1. SELECT * FROM pgfadvise_willneed('viid_vehicle.vehiclestructured');
  2. EXPLAIN  ANALYZE  SELECT * FROM viid_vehicle.vehiclestructured WHERE plateno LIKE '%S906%';
  3. Bitmap Heap Scan on vehiclestructured_a010000_20150101  (cost=83.84..1982.68 rows=496
  4. width=167) (actual time=74.726..88.282 rows=1913 loops=1)
  5.    Recheck Cond: ((plateno)::text ~~ '%S906%'::text)
  6.    Rows Removed by Index Recheck: 14
  7.    Heap Blocks: exact=1908
  8.    ->  Bitmap Index Scan on idx_vehiclestructured_a000000_20150101_plateno_like  (cost=
  9. 0.00..83.72 rows=496 width=0) (actual time=74.455..74.455 rows=1927 loops=1)
  10.          Index Cond: ((plateno)::text ~~ '%S906%'::text)
  11.  Planning time: 360.554 ms
  12.  Execution time: 88.953 ms

可以看出当将表手动加载到系统内存中时,查询效率是成倍地递增。

Pgfincore适用于数据预热,当数据库启动时,查询效率是会慢的,这样能够提升效率。

适用于下面这个生产场景:对查询效率的要求比较高,查询的数据比较固定,且系统的读写频率不高的情况下,可以使用。

注意:当操作系统的写入太过频繁,导致缓存过多的话,会把加载到内存中的表挤出去。

Pgfincore这个工具只是把表加载到内存中,但是没有把表固定在内存当中。

文章知识点与官方知识档案匹配,可进一步学习相关知识
PostgreSQL技能树首页概览6103 人正在系统学习中

[转帖]PostgreSQL(三) 内存参数优化和原理(work_mem)内存表 pgfincore插件使用方法的更多相关文章

  1. JVM堆内存参数优化,让性能飞起来

    堆内存是Java进程的重要组成部分,几乎所有与应用相关的内存空间都和堆有关.现在主要介绍与堆内存相关的参数设置,这些参数对Java虚拟机中非常重要的,也是对程序性能有着重要的影响.让你彻底脱离OOM内 ...

  2. tomcat 内存参数优化示例

    https://www.cnblogs.com/cornerxin/p/9304100.html

  3. Nginx笔记总结三:内核参数优化

    net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 1800 net.ipv4.ip_conntrack_max = 16777216 ...

  4. TomcatJVM参数优化降低内存使用率(重点)!

    JVM是jdk最底层的支柱 做JVM参数优化主要是为了改善服务器性能以及内存使用率 JAVA堆分为三大部分:(新生代.老年代.永久代) ================================ ...

  5. Linux新系统的安全优化和内核参数优化

    拿到一个新的linux系统需要做的安全和内核优化,主要是为了提升系统安全和提升性能,满足后续的应用需要.这里简单记录一下拿到一个新的系统需要做的一些事情,仅此抛砖引玉,具体可根据自己实际情况进行设置. ...

  6. Flex内存泄露解决方法和内存释放优化原则

    Flex内存泄露解决方法和内存释放优化原则 你对Flex内存泄露的概念是否了解,这里和大家分享一下Flex内存释放优化原则和Flex内存泄露解决方法,希望本文的介绍能让你有所收获. Flex内存释放优 ...

  7. [转帖]PostgreSQL 参数调整(性能优化)

    PostgreSQL 参数调整(性能优化) https://www.cnblogs.com/VicLiu/p/11854730.html 知道一个 shared_pool 文章写的挺好的 还没仔细看 ...

  8. [转帖]Java虚拟机(JVM)体系结构概述及各种性能参数优化总结

    Java虚拟机(JVM)体系结构概述及各种性能参数优化总结 2014年09月11日 23:05:27 zhongwen7710 阅读数 1437 标签: JVM调优jvm 更多 个人分类: Java知 ...

  9. 【大数据面试】【框架】Shuffle优化、内存参数配置、Yarn工作机制、调度器使用

    三.MapReduce 1.Shuffle及其优化☆ Shuffle是Map方法之后,Reduce方法之前,混洗的过程 Map-->getPartition(标记数据的分区)-->对应的环 ...

  10. PostgreSQL 配置内存参数

    对于任何数据库软件,内存配置项都是很重要的配置项.在 PostgreSQL 主要有以下几个内存配置参数. shared_buffers: integer 类型,设置数据库服务器将使用的共享内存缓冲区数 ...

随机推荐

  1. Java数组常见的几种排序。

    public class code2 { public static void main(String[] args) { int[] x = {37, 89, 23}; for (int z = 0 ...

  2. 毕业季 | 华为专家亲授面试秘诀:如何拿到大厂高薪offer?

    摘要:了解大厂面试流程.要求以及技巧,做好充分准备,赢在职场起跑线. 本文分享自华为云社区<毕业季 | 华为专家亲授面试秘诀:如何拿到大厂高薪offer?>,作者:华为云社区精选. 同学们 ...

  3. “互联网+”大赛之AI创新应用赛题攻略:大胆脑洞,共绘智慧生活蓝图

    摘要:本次"互联网+"大赛AI创新应用赛题的设置是希望学生可以从日常实际应用需求出发,结合自己的奇思妙想,提升智能终端用户的使用体验,为构建万物互联的智能世界贡献一份力量. 本文分 ...

  4. JS对象拷贝:深拷贝和浅拷贝

    摘要:对象拷贝,简而言之就是将对象再复制一份,但是,复制的方法不同将会得到不同的结果. 本文分享自华为云社区<js对象深浅拷贝,来,试试看!>,作者: 北极光之夜.. 一.速识概念: 对象 ...

  5. 一分钟带你了解Huawei LiteOS组件开发指南

    摘要:本文将基于Huawei LiteOS系统,从组件定义开始带你走进组件开发指南. 本文分享自华为云社区<一分钟带你了解Huawei LiteOS之组件开发指南>,作者: Lionlac ...

  6. HanLP — HMM隐马尔可夫模型 -- 训练&预测

    BMES => B-begin:词语开始.M-middle:词语中间.E-end:词语结束.S-single:单独成词 训练的过程,就是求三个矩阵的过程 初始概率矩阵 转移概率矩阵 发射矩阵 每 ...

  7. PPT 动态迷幻图谱

    迷幻动画的本质拆解 插件: islide + 软件: PowerPoint https://www.islide.cc/ 圆型 画一个正圆,无填充色,边框 2.25磅 左边红色.右边黄色.中间两个透明 ...

  8. yaml/json/ini 配置读取

    ConfigParser 安装 ConfigParser 是解析配置文件的第三方库,须要安装 pip install ConfigParser pip install ConfigParser Con ...

  9. 100天搞定机器学习|Day60 遇事不决,XGBoost

    XGBoost 是一种集大成的机器学习算法,可用于回归,分类和排序等各种问题,在机器学习大赛及工业领域被广泛应用.成功案例包括:网页文本分类.顾客行为预测.情感挖掘.广告点击率预测.恶意软件分类.物品 ...

  10. AI 视频云 VS 窄带高清,谁是视频时代的宠儿

    随着网络技术的逐渐改善,各类视频消息成为媒体传播的主要选择手段.但其实支撑着视频传播的并不单单是网络技术,还有视频转码与压缩技术.这类技术下分很多,比如曾经被频繁提到的 H.265,比如时下热门的窄带 ...