调整PostgreSQL设置以优化性能

默认情况下,未为工作负载配置PostgreSQL。 设置默认值可确保PostgreSQL在所有资源最少的地方都能正常运行。 所有数据库设置都有默认设置。 数据库管理员或开发人员的主要职责是配置PostgreSQL以适合其系统负载。 在此博客中,我们将概述有关根据工作负载调整PostgreSQL数据库设置以提高数据库性能的基本建议。

请记住,虽然优化PostgreSQL服务器配置可以提高性能,但数据库设计人员在编写查询时也应小心。 如果查询执行可以使用索引的全表扫描,或者执行繁重的联接或昂贵的聚合操作,则即使数据库设置配置正确,系统仍可能无法正常工作。 在编写数据库查询时,重要的是要注意性能。

但是,数据库参数也非常重要,因此让我们看一下最有可能提高性能的八个参数。

自定义PostgreSQL选项


PostgreSQL使用自己的缓冲区,也使用缓冲的内核IO。 这意味着数据两次存储在内存中,首先在PostgreSQL缓冲区中,然后在内核缓冲区中。 与其他数据库不同,PostgreSQL不提供直接I / O。 这称为双缓冲。 PostgreSQL缓冲区称为shared_buffer ,它是大多数操作系统中最有效的自定义参数。 此参数设置PostgreSQL将用于缓存的已分配内存量。

shared_buffer的默认值设置得很低,您不会从中获得很多好处。 这是因为某些机器和操作系统不支持更高的值。 但是在大多数现代机器中,您需要增加此值以获得最佳性能。

推荐值是计算机总RAM的25%。 您应该尝试一些较低和较高的值,因为在某些情况下,设置超过25%可以获得良好的性能。 但是实际配置取决于您的机器和工作数据集。 如果您的工作数据集可以轻松放入RAM中,则可以增加shared_buffer的值,使其包含整个数据库,并且整个工作数据集都可以位于缓存中。 但是,您显然不想为PostgreSQL保留所有RAM。

值得注意的是,在生产环境中,尽管应始终执行测试以达到正确的平衡,但是良好的性能确实对shared_buffer至关重要。

检查shared_buffer的值
testdb=# SHOW shared_buffers; shared_buffers ---------------- 128MB (1 row) 

注意 :请小心,因为某些内核不支持更大的值 ,尤其是在Windows上。

wal_buffers


PostgreSQL首先将WAL(预记录日志)中的条目写入缓冲区,然后将这些缓冲区刷新到磁盘。 wal_buffers定义的默认缓冲区大小为16 MB。 但是,如果您有许多并发连接,则更高的值可以提高性能。

Effective_cache_size


Effective_cache_size提供了可用于磁盘缓存的内存的估计值。 这仅是一个准则,并非分配的内存或缓存的确切数量。 它不分配实际的内存,但告诉优化器内核中可用的缓存量。 如果此参数设置得太低,则查询计划程序可能会决定不使用某些索引,即使它们很有用。 因此,设置一个大的值总是有意义的。

work_mem


此设置用于复杂的排序。 如果需要进行复杂的排序,请增加work_mem的值以获得良好的结果。 在内存中排序比在磁盘上排序数据快得多。 将其设置为很高的值可能会导致环境出现存储瓶颈,因为此选项与用户排序操作有关。 因此,如果有许多用户尝试执行排序操作,那么系统将突出显示:

 work_mem * total sort operations 

适用于所有用户。 全局设置此参数会导致很高的内存使用率。 因此,强烈建议您在会话级别进行更改。

work_mem = 2MB
 testdb=# SET work_mem TO "2MB"; testdb=# EXPLAIN SELECT * FROM bar ORDER BY bar.b; QUERY PLAN ----------------------------------------------------------------------------------- Gather Merge (cost=509181.84..1706542.14 rows=10000116 width=24) Workers Planned: 4 -> Sort (cost=508181.79..514431.86 rows=2500029 width=24) Sort Key: b -> Parallel Seq Scan on bar (cost=0.00..88695.29 rows=2500029 width=24) (5 rows) 

在514431.86评估初始请求排序节点。 成本是任意计算的单位。 对于以上请求,我们只有work_mem 2 MB。 为了进行测试,让我们将该值增加到256 MB,看看它是否影响成本。

work_mem = 256MB
 testdb=# SET work_mem TO "256MB"; testdb=# EXPLAIN SELECT * FROM bar ORDER BY bar.b; QUERY PLAN ----------------------------------------------------------------------------------- Gather Merge (cost=355367.34..1552727.64 rows=10000116 width=24) Workers Planned: 4 -> Sort (cost=354367.29..360617.36 rows=2500029 width=24) Sort Key: b -> Parallel Seq Scan on bar (cost=0.00..88695.29 rows=2500029 width=24) 

请求成本从514431.86降低到360617.36,即降低了30%。

maintenance_work_mem


maintenance_work_mem是用于维护任务的内存参数。 默认值为64 MB。 设置较大的值有助于完成诸如VACUUM,RESTORE,CREATE INDEX,ADID FOREIGN KEY和ALTER TABLE等任务。

maintenance_work_mem = 10MB
 postgres=# CHECKPOINT; postgres=# SET maintenance_work_mem to '10MB'; postgres=# CREATE INDEX foo_idx ON foo (c); CREATE INDEX Time: 170091.371 ms (02:50.091) 


maintenance_work_mem = 256MB
 postgres=# CHECKPOINT; postgres=# set maintenance_work_mem to '256MB'; postgres=# CREATE INDEX foo_idx ON foo (c); CREATE INDEX Time: 111274.903 ms (01:51.275) 

如果将maintenance_work_mem参数设置为仅10 MB,则索引创建时间为170091.371 ms,但是当将maintenance_work_mem参数增加至256 MB时,索引创建时间将减少为111274.903 ms。

同步提交


用于确保事务提交在向客户端返回成功完成状态之前等待WAL写入磁盘。 这是性能和可靠性之间的折衷。 如果您的应用程序的设计方式使性能比可靠性更为重要,请禁用sync_commit 。 在这种情况下,事务将很快提交,因为它不会等待WAL文件被重置,但是会损害可靠性。 如果服务器发生故障,即使客户端收到指示事务提交成功完成的消息,数据也可能会丢失。

checkpoint_timeout,checkpoint_completion_target


PostgreSQL将更改写入WAL。 检查点进程将数据刷新到文件。 发生断点(CHECKPOINT)时执行此操作。 这是一项昂贵的操作,并且可能导致大量的IO操作。 这整个过程涉及昂贵的磁盘读/写操作。 用户始终可以在必要时启动检查点任务(CHECKPOINT),或使用checkpoint_timeoutcheckpoint_completion_target参数自动启动该任务。

checkpoint_timeout参数用于设置WAL断点之间的时间。 将其设置得太低会减少故障后的恢复时间,因为有更多的数据正在写入磁盘,但也会降低性能,因为每个检查点最终都会消耗宝贵的系统资源。

checkpoint_completion_target是完成检查点的检查点之间的时间分数。 高频检查点会影响性能。 为了顺利完成检查点作业, checkpoint_timeout必须为低。 否则,操作系统将累积所有脏页,直到观察到该比率为止,然后产生较大的重置。

结论


您可以调整更多选项来获得更好的性能,但是它们的影响要小于此处突出显示的选项。 最后,我们必须始终记住,并非所有参数都与所有类型的应用程序相关。 设置选项时,某些应用程序可以更好地工作,而有些则不能。 PostgreSQL数据库设置必须根据应用程序及其运行所在的操作系统的特定需求进行调整。

Source: https://habr.com/ru/post/zh-CN458952/


All Articles