postgresql数据库常见优化参数

1,062 阅读5分钟

postgresql数据库常见优化参数

配置参数调优

    配置参数调优用于修改pg工作参数,一般在安装完数据库软件以后应立即进行着手调整,该参数文件名称为postgresql.conf,参数内容修改后需要重启数据库软件才能生效。

    如果不确定每一个参数的用途或者想偷懒,可以使用PG在线配置参数优化工具进行配置:PGTune - calculate configuration for PostgreSQL

连接数量

  该参数用于控制最大连接到PG数据库的客户端连接总数,默认安装的pg最大连接参数为100,需要根据服务器内存大小及内存配置参数进行调整,如调整为1000。

max_connections = 1000

work_mem

  该参数用于为单条SQL执行分配最大内存,当内存不够用时会出现写硬盘临时文件的情况,但是需要注意一条SQL内如果有多个order by话,每一个order by单独按照work_mem配置值占用内存。

  默认情况下work_mem配置为4M内存,当涉及到较大数据量的查询、排序等操作时4M内存不够用时就会出现写硬盘临时数据的情况,磁盘IO一般都比较慢,可以适度调大该参数,具体调整为多少取决于SQL的复杂程度,建议设置work_mem为16M以上的数值,同时配合log_temp_files配置参数观察SQL查询是否经常出现写硬盘临时文件的情况。

postgres=# EXPLAIN ANALYZE SELECT id, name FROM people_warm ORDER BY id;

QUERY PLAN                                                                     


 Gather Merge  (cost=5019047.44..9880499.52 rows=41666680 width=37) (actual time=567717.158..594007.752 rows=50000000 loops=1)

  Workers Planned: 2

  Workers Launched: 2

  ->  Sort  (cost=5018047.42..5070130.77 rows=20833340 width=37) (actual time=566715.013..570783.692 rows=16666667 loops=3)

        Sort Key: id

        Sort Method: external merge  Disk: 767080kB              #注意看这里,work_mem内存不够用了,查询计划选择了使用磁盘写临时文件的方式进行了排序操作

        Worker 0:  Sort Method: external merge  Disk: 765288kB   

        Worker 1:  Sort Method: external merge  Disk: 767304kB

        ->  Parallel Seq Scan on people_warm  (cost=0.00..776515.40 rows=20833340 width=37) (actual time=0.055..383585.941 rows=16666667 loops=3)

 Planning Time: 0.047 ms

 Execution Time: 597556.456 ms

建议配置值:

work_mem=16MB

shared_buffers

  shared_buffers里面一般用于缓存表、索引、执行计划等数据,数据库引擎查找数据时会优先在shared_buffers里面进行查找,建议配置为物理内存的1/4大小。

shared_buffers=20GB

effective_cache_size

    该参数不真实占用物理内存,属于查询优化器的一个估算参考值,用于确定查询数据时是走索引还是顺序扫描全表数据,一般配置为物理内存大小的1/2大小。

effective_cache_size=40GB

max_worker_processes

  改参数用于控制最大并发查询数量,默认值为8,建议调整为128或其他值。

max_worker_processes=128

maintenance_work_mem

  该参数用于指明数据库创建索引或autovacuum(自动清理统计)等管理维护进程的可用内存上限。

maintenance_work_mem=2GB

checkpoint_completion_target

  简单说该参数用于控制数据多久刷新写盘,写盘太频繁的话会降低系统IO效率,具体细节可以参考PgSQL · 特性分析 · 谈谈checkpoint的调度 (taobao.org)

checkpoint_completion_target=0.7

wal_buffers

    该参数默认为shared_buffers的值除以32,即取其32分之1,如果自动计算结果小于16M,可以直接配置为16MB

wal_buffers = 16MB

max_wal_size 

  该参数用于控制pg里面的wal日志最大占用多大磁盘空间。wal日志是用于数据回滚或主从流复制的关键核心,甚至pg对表里面的数据进行更改以后,保存在shared_buffers里面的脏页在事务提交后不是实时写盘,而是先确保写wal成功以后再定期同步真实表数据的。在出现异常时pg会根据wal日志进行回滚操作。该参数默认为1G,可以适度调大该参数到8G,关于该参数的介绍资料:

max_wal_size = 8GB

慢SQL记录

log_statement = all  #需设置跟踪所有语句,否则只能跟踪出错信息

log_min_duration_statement = 10000  #milliseconds,记录执行10秒及以上的语句

运维检查

查看当前任务

SELECT 

    procpid, 

    start, 

    now() - start AS lap, 

    current_query 

FROM 

    (SELECT 

        backendid, 

        pg_stat_get_backend_pid(S.backendid) AS procpid, 

        pg_stat_get_backend_activity_start(S.backendid) AS start, 

      pg_stat_get_backend_activity(S.backendid) AS current_query 

    FROM 

        (SELECT pg_stat_get_backend_idset() AS backendid) AS S 

    ) AS S 

WHERE 

  current_query <> '' 

ORDER BY lap DESC;

PG_TOP

  pgtop需要单独安装,可以下载与服务器CPU指令集对应的安装包手动进行安装,使用时切到postgres用户,然后再运行pg_top即可。

查看磁盘IO繁忙程度

  先安装sysstat软件包,然后iostat -x 1 查看IO使用率。

查看执行计划

EXPLAIN ANALYZE 你的查询SQL

  以下举例说明执行计划如何查看

explain ANALYZE with recursive tbl_result as (  

  select dept_id from admin_dept where dept_id=13

    union all  

  select t2.dept_id from tbl_result t1 join admin_dept t2 on t1.dept_id=t2.parent_id  

 )  

select count(0) as zs from admin_employee a inner join tbl_result b on a.main_dept_id=b.dept_id 

 得到结果如下:

  屏幕最下方的Execution Time :60.772ms说明整个查询执行耗时60毫秒,屏幕顶部的(cost=18980.91..18980.92 rows=1 width=8) 中的第一个数值18980.91代表返回第一条数据时的开销成本总和,第二个数值18980.92代表返回所有数据的成本开销,这个成本开销的具体计算权重可以看这里:

- Planner Cost Constants -

#seq_page_cost = 1.0                    # measured on an arbitrary scale。扫描一个数据块(一页)的成本(IO成本)

#random_page_cost = 4.0                # same scale as above。随机获取一个数据块(一页)的成本(IO成本)

#cpu_tuple_cost = 0.01                  # same scale as above。获取一行数据的CPU成本

#cpu_index_tuple_cost = 0.005          # same scale as above。获取一个索引项的CPU成本

#cpu_operator_cost = 0.0025            # same scale as above。每个操作符的CPU成本

  actual time是真实执行查询的时间开销,单位毫秒,两个数值代表该任务的开始和结束时间,如  ->  Nested Loop  (cost=0.43..4874.91 rows=35082 width=0) (actual time=0.037..52.871 rows=65737 loops=1)  说明开始时间是0.037毫秒,执行完该任务是52.871毫秒,因为整个查询耗时60.772毫秒,而这一步就耗时了52.871-0.037=52.834毫秒,如果有优化空间的话就可以优先考虑优化该部分的SQL内容。