延迟升级:PostgreSQL 12如何提高性能


PostgreSQL 12是“世界上最好的开源关系数据库”的最新版本,它在几周内发布(如果一切按计划进行的话)。 这符合通常的时间表-每年发布一次具有很多新功能的新版本,坦率地说,这令人印象深刻。 因此,我成为PostgreSQL社区的活跃成员。


我认为,与以前的发行版不同,PostgreSQL 12不包含一个或两个革命性的功能(例如分区或查询并发)。 我曾经开玩笑说PostgreSQL 12的主要功能是更稳定。 管理关键业务数据时,这不是您所需要的吗?


但是PostgreSQL 12不仅限于此:有了新功能和增强功能,应用程序将可以更好地运行, 您只需要升级!


(嗯,也许甚至重建了索引,但是在此版本中,它并不像我们以前那样可怕。)


升级PostgreSQL并立即享受显着的改进而不会产生不必要的手势将非常有用。 几年前,我分析了从PostgreSQL 9.4到PostgreSQL 10的升级,并了解了由于PostgreSQL 10中查询并行度的提高,应用程序如何加速。而且,最重要的是,几乎不需要我(只需设置max_parallel_workers配置max_parallel_workers )。


同意,在升级后,应用程序可以更好地工作,这是很方便的。 我们正在努力取悦用户,因为PostgreSQL有更多的用户。


简单升级到PostgreSQL 12会让您感到高兴吗? 我现在告诉你。


重大索引改进


如果不建立索引,数据库将不会走得太远。 以及如何快速查找信息? PostgreSQL的基本索引系统称为B-tree 。 此类索引针对存储系统进行了优化。


我们只使用CREATE INDEX ON some_table (some_column) ,而PostgreSQL在不断插入,更新和删除值的同时,保持索引处于最新状态也做得很好。 一切都是靠自身运作的,就好像靠魔术一样。


但是PostgreSQL索引有一个问题-它们膨胀并且占用了额外的磁盘空间,并且检索和更新数据的性能降低了。 “膨胀”是指无效地维护索引结构。 这可能是(也可能不是)由于VACUUM删除了垃圾元组(感谢提供给Peter Geoghegan的信息)。 在索引不断变化的工作负载中,索引膨胀尤其明显。


PostgreSQL 12极大地提高了B树索引的性能,并且对TPC-C等测试的实验表明,现在平均使用的空间减少了40%。 现在,由于索引变得越来越小,我们不仅在维护B树索引(即在写操作)上,而且在数据提取上花费的时间都更少。


主动更新其表的应用程序(通常是OLTP应用程序( 实时事务处理 ))在使用磁盘和处理请求方面效率更高。 磁盘空间越多,无需升级基础架构即可增加数据库的增长空间。


一些升级策略要求重建B树索引来利用这些索引(例如pg_upgrade不会自动重建索引)。 在早期版本的PostgreSQL中,重建表中的大索引会导致大量停机,因为当时无法进行更改。 但是PostgreSQL 12还有一个很酷的技巧:您现在可以与REINDEX CONCURRENTLY命令并行地重建索引,以完全避免停机。


PostgreSQL 12对索引基础结构进行了其他改进。 不可缺少的另一件事是预写日志,它也是WAL(预写日志)。 预写日志记录了PostgreSQL发生故障和复制时的每个事务。 应用程序在某个时间点将其用于备份和还原 。 当然,预写日志已写入磁盘,这可能会影响性能。


PostgreSQL 12在构建索引时减少了由GiST,GIN和SP-GiST索引创建的WAL的开销。 这提供了许多明显的优势:WAL记录占用更少的磁盘空间,并且数据的复制速度更快,例如,在从故障中恢复或在某个时间点恢复时。 如果在应用程序中使用此类索引(例如,基于PostGIS的地理空间应用程序经常使用GiST索引),则这是另一个功能,它将极大地提高性能,而无需您付出任何努力。


分区-更大,更好,更快


PostgreSQL 10引入了声明式分区 。 PostgreSQL 11使它更易于使用。 在PostgreSQL 12中,您可以更改部分的比例。


在PostgreSQL 12中,分区系统的性能要好得多,尤其是在表中有成千上万的节的情况下。 例如,如果查询仅影响一个表中的几个部分(其中有数千个部分),那么它将更快地运行。 不仅针对这些类型的查询,性能得到了改善。 您还将注意到在具有多个分区的表中INSERT操作是如何加速的。


使用COPY写入数据-顺便说一句,这是批量加载数据的好方法,并且这里是接收JSON的示例-在PostgreSQL 12的分区表中也变得更加高效。 有了COPY,一切都变得如此之快,但是在PostgreSQL 12中,一切顺利。


得益于这些好处,PostgreSQL可以存储更大的数据集并使检索更加容易。 不用您费力。 例如,如果应用程序包含许多部分,则它会记录时间序列数据,那么简单的升级将显着提高其性能。


尽管这种改进并不完全来自“升级和欢喜”类别,但是在PostgreSQL 12中,您可以创建引用分区表的外键,这样使用分区就很有趣。


用查询更好


当将补丁应用于内置的通用表表达式 (它们是CTE,它们也是WITH查询)时,我很想写一篇有关PostgreSQL应用程序开发人员如何感到高兴的文章 。 这是可以加速应用程序的功能之一。 当然,除非您使用的是CTE。


我经常注意到,SQL的新手喜欢使用CTE:如果以某种方式编写它们,您会直接感觉到您正在编写命令式程序。 我个人很喜欢重写这些查询,以免使用 CTE并提高性能。 现在一切都不同了。


PostgreSQL 12允许您嵌入没有副作用( SELECT )的特定类型的CTE,仅在查询结束时使用一次。 如果我保留我重写的CTE的请求统计信息,那么大多数将属于这一类。 这有助于开发人员编写可理解的代码,这些代码现在也可以快速运行。


而且,PostgreSQL 12优化了SQL本身的执行,您无需执行任何操作。 尽管现在可能不需要优化此类查询,但是PostgreSQL继续致力于查询优化这一点很棒。


即时(JIT)-现在默认


在支持LLVM的 PostgreSQL 12系统上,默认情况下启用JIT编译。 首先,您获得对某些内部操作的JIT支持,其次,在选择列表(在SELECT之后拥有)中使用表达式(最简单的示例是x + y)查询,聚合,带有WHERE子句的表达式以及其他查询可以使用JIT来提高性能。


由于默认情况下PostgreSQL 12中包含JIT,因此性能会自行提高,但是我建议在PostgreSQL 11中测试该应用程序,在该应用程序中,JIT只是用来衡量查询性能并查看是否需要调整任何内容。


但是PostgreSQL 12的其他新功能呢?


PostgreSQL有12吨很酷的新功能-从使用标准SQL / JSON路由表达式检查JSON数据的能力到使用clientcert=verify-full参数的多因素身份clientcert=verify-full ,创建的列等等。 足够一个单独的职位。


与PostgreSQL 10一样,PostgreSQL 12将在升级后立即改善整体性能。 当然,您可以采用自己的方式-像我对PostgreSQL 10所做的那样,先在工作系统中的类似条件下测试应用程序,然后再进行改进,即使PostgreSQL 12已经比我预期的要稳定,也不要懒于测试应用程序的质量,在将它们投入生产之前。

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


All Articles