对于列压缩选项,PostgreSQL 14提供了新的压缩方法LZ4。与TOAST中现有的PGLZ压缩方法相比,LZ4压缩更快。本文介绍如何使用整个选项,并和其他压缩算法进行性能比较。

背景

PG中,页是存储数据的单位,默认是8KB。一般情况下,一行数据不允许跨页存储。然而,有一些变长的数据类型,存储的数据可能超出一页大学。为了克服整个限制,大字段域会被压缩或者分割成多个物理行。这个技术就是TOAST:

https://www.postgresql.org/docs/14/storage-toast.html

默认情况下,如果表中有变长列,行数据的大小超过TOAST_TUPLE_THRESHOLD(默认2KB)就会触发TOAST。首先,会先压缩数据;压缩后如果仍然太大,会溢出存储。需要注意,如果列的存储策略指定EXTERNAL/PLAIN,压缩会被禁止。

PG14之前版本,TOAST仅支持一个压缩算法PGLZ(PG内置算法)。但是其他压缩算法可能比PGLZ更快或者有更高的压缩率。PG14中有了新压缩选项LZ4压缩,这是一个以速度著称的无损压缩算法。因此我们可以期望它有助于提高TOAST压缩和解压缩的速度。

如何使用LZ4?

为了使用LZ4压缩特性,在编译时需要指定--with-lz4,并且在操作系统中按照LZ4库。通过GUC参数default_toast_compression可以指定PG实例的TOAST默认压缩算法。可以在postgresql.conf中配置,也可以通过SET命令仅改变当前连接:

postgres=# SET default_toast_compression=lz4;
SET

在CREATE TABLE创建表时指定列压缩算法:

postgres=# CREATE TABLE tbl (id int,
postgres(#                   col1 text COMPRESSION pglz,
postgres(#                   col2 text COMPRESSION lz4,
postgres(#                   col3 text);
CREATE TABLE
postgres=# \d+ tbl
Table "public.tbl"
Column | Type    | … | Storage  | Compression | …
-------+---------+---+----------+-------------+ …
id     | integer |   | plain    |             |
col1   | text    |   | extended | pglz        |
col2   | text    |   | extended | lz4         |
col3   | text    |   | extended |             |
Access method: heap

我们使用\d+命令可以看到所有列的压缩算法。如果列不支持或者没有指定压缩算法,那么会在Compression列显示空格。上面的例子中,id列不支持压缩算法,col1列使用PGLZ,col2使用LZ4,col3没有指定压缩算法,那么它会使用默认的压缩算法。

可以通过ALTER TABLE修改列压缩算法,但需要注意,修改后的算法仅影响执行整个命令后的insert数据。

postgres=# INSERT INTO tbl VALUES (1, repeat('abc',1000), repeat('abc',1000),repeat('abc',1000));
INSERT 0 1
postgres=# ALTER TABLE tbl ALTER COLUMN col1 SET COMPRESSION lz4;
ALTER TABLE
postgres=# INSERT INTO tbl VALUES (2, repeat('abc',1000), repeat('abc',1000),repeat('abc',1000));
INSERT 0 1
postgres=# SELECT id,
postgres-#        pg_column_compression(id)   AS compression_colid,
postgres-#        pg_column_compression(col1) AS compression_col1,
postgres-#        pg_column_compression(col2) AS compression_col2,
postgres-#        pg_column_compression(col3) AS compression_col3
postgres-# FROM tbl;
id | compression_colid | compression_col1 | compression_col2 | compression_col3
---+-------------------+------------------+------------------+------------------1 |                   | pglz             | lz4              | lz42 |                   | lz4              | lz4              | lz4
(2 rows)

可以看到在修改压缩算法前插入的行,col1仍使用PGLZ压缩算法,即使将压缩算法从PGLZ修改到了LZ4。(那么,修改后进行解压时使用哪个算法呢?)

需要注意,如果从其他表扫数据插入本表,例如CREATE TABLE ...AS...或者INSERT INTO...SELECT...,插入的数据使用的压缩算法仍然使用原始数据的压缩方法。pg_dump和pg_dumpall也添加了选项--no-toast-compuression,使用整个选项后,不会dump出TOAST压缩选项。

性能比较

测试了LZ4和PGLZ压缩率和压缩速度。并添加了未压缩数据的测试结果(指定存储策略为EXTERNAL),对于未压缩数据,没有压缩和解压的耗时,但读和写数据的时间会增加。

测试使用的数据:PG documents(一行数据一个HTML文件);SilesiaCorpus提供的数据,包括HTML、Text、源代码、可执行二进制文件、图片:

https://github.com/MiloszKrajewski/SilesiaCorpus

测试机器使用Intel® Xeon® Silver 4210 CPU @2.20GHz with 10 cores/20 threads/2 sockets。

使用pgbench测试SQL语句执行时间,pg_table_size检查表大学(每次执行前都执行VACUUM FULL排除死记录的影响)。

压缩率

PGLZ和LZ4的压缩率都依赖于重复数据,重复的元组越多,压缩率越高。但是如果PG评估这样的压缩率不好时,就不会执行压缩,即使数据大小达到了阈值。因为压缩并没有高效节省磁盘空间,还会带来解压锁的额外时间和资源消耗。

当前PG14中,PGLZ需要至少25%的压缩率,LZ则仅比未压缩数据时小即可。我比较了LZ4、PGLZ的表与未压缩表大小。可以看到,大部分场景下,PGLZ的压缩率稍微好点,压缩率评价为2.23,LZ4的压缩率为2.07。这意味着PGLZ可以节省7%的磁盘空间。

Figure 1 - Comparing table sizes (in KB)

压缩/解压缩速度

Insert和查询时TOAST数据会被压缩和解压缩。因此,我执行一些SQL语句查看不同压缩算法带来的影响。

首先比较了INSERT语句,列使用LZ、PGLZ和未使用压缩时的性能。可以看到与未压缩数据比,LZ4耗费稍微多一点时间,PGLZ耗费时间更多。LZ4的压缩时间比PGLZ平均节省20%。这是一项非常显著的改进。

Figure 2 - Comparing INSERT performance

下面比较SELECT。与PGLZ相比,LZ4可以节省20%的时间,与未压缩数据相比,没有太大差别。解压缩的消耗已经降到了很低了。

Figure 3 - Comparing SELECT performance

再比较16个客户端的INSERT语句并发。与PGLZ相比使用LZ4的单大文件(HTML,英文文本,源代码,二进制执行文件,图片)的压缩性能快60%-70%。插入多个小文件(PG文档),性能提升不大。和未压缩的数据相比,有巨大提升,猜测使用压缩减少了写入磁盘的数据量。

Figure 4 - Comparing INSERT performance with 16 clients

16个客户端的SELECT,多数场景下,LZ4性能优于PGLZ:

Figure 5 - Comparing SELECT performance with 16 clients

同样也比较了使用字符串函数的SELECT、UPDATE处理文本的速度。整个场景下LZ4优于PGLZ。LZ4压缩算法的数据与未压缩数据相比,函数处理的速度几乎一样,LZ4算法几乎不会影响字符串操作速度。

Figure 6 - Comparing performance using string functions

与PGLZ相比,LZ4压缩和解压缩TOAST数据更加高效,并提供很好的性能。和未压缩数据相比,查询速度几乎一样,和PGLZ相比,插入快80%。当然某些场景下压缩率不太好,但如过你想要提升执行速度,强烈推荐使用LZ4算法。

同样需要注意,需要考虑表中的数据是否合适压缩。如果压缩率不好,它仍然会尝试压缩数,然后放弃。这将导致额外的内存资源浪费,并极大影响插入数据的速度。

未来

LZ4对TOAST的压缩和解压缩性能带来了很大提升。除了LZ4,还有很多其他压缩算法比如Zstandard。支持Zstandard用户可以得到比PGLZ更好的压缩率。LZ4 HC具有比LZ4解压98.5%的压缩速度,但是可以大幅提升压缩率。希望未来PG版本可以使用更多的压缩算法。

除了TOAST外,其他场景也需要压缩。据我所知,目前开发版本已经支持WAL的LZ4压缩,这是一项令人兴奋的特性。

原文

https://www.postgresql.fastware.com/blog/what-is-the-new-lz4-toast-compression-in-postgresql-14

PostgreSQL 14中TOAST的新压缩算法LZ4,它有多快?相关推荐

  1. PostgreSQL 14 版本发布,快来看看有哪些新特性!

    文章目录 性能增强 数据类型和 SQL 管理功能 复制和恢复 安全增强 更多特性 大家好!我是只谈技术不剪发的 Tony 老师. PostgreSQL 全球开发组于 2021-05-20 发布了 Po ...

  2. Java 14 中令人期待的五大新特性!

    随着新的 Java 发布生命周期的到来,新版本预计将于 2020 年 3 月发布,本文将对其中的 5 个主要特性作些概述. 作者 | Sylvain Saurel 译者 | 苏本如,责编 | 郭芮 出 ...

  3. 极客日报:阿里旗下App接入微信支付;马斯克成世界首富;PostgreSQL 14 RC 1发布

    一分钟速览新闻点! 阿里回应App接入微信支付 抖音起诉知乎名誉侵权 小米上诉"小米穿戴"图形商标被驳回 拼多多.美团已支持众多主流支付渠道 清华AI学生华智冰首次露正脸唱歌 快手 ...

  4. ios 图像翻转_在iOS 14中使用计算机视觉的图像差异

    ios 图像翻转 Human eyes are very receptive to visual representations. Similarly, computer vision enables ...

  5. 你好,了解一下Java 14带来的一系列新功能

    Java 14带来的一系列新功能 Java 14包含比前两个发行版更多的新功能-其中大多数旨在简化编码. 劳尔·加布里埃尔·乌尔玛(Raoul-Gabriel Urma) 下载本文的PDF Java ...

  6. C++14学习记录:新语言功能特性

    本篇笔记汇总了C++14中的主要新语言功能特性,根据个人理解与查阅的资料进行记录. 主要参考地址:cppreference C++14主要是在C++11标准之上的一些补充,所以相对的内容较少一些. 目 ...

  7. 探索PostgreSQL 14新特性--SEARCH和CYCLE

    探索PostgreSQL 14新特性--SEARCH和CYCLE PG14的SEARCH和CYCLE新功能大大简化了递归查询的方式,本文给出一些基于旅行计划的示例. 创建数据库 本文示例基于任何PG1 ...

  8. 苹果马上又要更新系统,iOS 14.5 Beta中的所有新功能

    苹果今天发布了即将发布的iOS 14.5和iPadOS 14.5更新的第一个beta版本,尽管新软件是应用程序开发人员必须遵守应用程序跟踪透明度规则的最后期限,但还有一些其他值得注意的变化. Appl ...

  9. PostgreSQL 14及更高版本改进

    PostgreSQL 14及更高版本 本文谈谈PG14中的关键特性及社区中正在谈论PG15及更高版本的内容. PG14的主要特性 逻辑复制的改进 PG14中对逻辑复制进行了几项增强: 1) 正在进行中 ...

最新文章

  1. lind.ddd博客笔记索引
  2. PowerBuilder窗口之间传递多参数的方法
  3. 机器人或抢走2000万人“饭碗”
  4. DCOM 示例:演示如何远程调用 COM 对象
  5. QT的QSslPreSharedKeyAuthenticator类的使用
  6. Flask 项目布局
  7. mysql upgrade 失败_`mysql_upgrade`失败,没有给出真正的理由
  8. matlab读取黑白图目标位置的坐标,matlab对图像处理——裁剪 获取灰度图 获取坐标点...
  9. OpenShift 4.3 - 基于虚拟机的BareMetal离线安装(5-6)
  10. ubuntu ffmpeg 批量修改视频分辨率
  11. Java URLDecoder和URLEncoder
  12. 初一网络计算机基础知识,初一计算机基础知识复习题da.docx
  13. 个人投资课 张潇雨_张潇雨《个人投资课》学习笔记
  14. OpenFeign简介
  15. 使用cgo,由于内存释放导致内存无效,引起的http crash
  16. php js广告,JavaScript_用JS调用谷歌 AdSense广告的方法, 具体的google广告的js文件做 - phpStudy...
  17. Motion Planning中的问题与挑战
  18. 科创人·StreamNative翟佳:开源模式价值为王,基础软件的未来在国内社区
  19. 让吹牛都能全世界最棒
  20. 什么是Session 如何使用Session

热门文章

  1. 摩托罗拉v3android,一问易答:MOTO推出Android版V3靠谱吗!
  2. Three.js实例详解___旋转的精灵女孩(附完整代码和资源)(三)
  3. matrix67 kmp算法讲解
  4. python asyncio tcp server_Python 的异步 IO:Asyncio 之 TCP Client
  5. 微信获取用户列表的json字符串解析
  6. DBSwitch阉割版实现异构数据库表结构同步
  7. 【2021最新版】Spring Boot面试题总结(92道题含答案解析)
  8. android 静态方法 构造方法,Android通过静态内部类构建Handler提示构造方法过时
  9. php xdebug测试,使用XDebug调试及单元测试覆盖率分析
  10. flex伸缩布局之携程网项目