首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >数据压缩60%让“PostgreSQL” SQL运行更快,这不科学呀?

数据压缩60%让“PostgreSQL” SQL运行更快,这不科学呀?

作者头像
AustinDatabases
发布2025-08-06 10:17:18
发布2025-08-06 10:17:18
7500
代码可运行
举报
文章被收录于专栏:AustinDatabasesAustinDatabases
运行总次数:0
代码可运行

在PolarDB 的非官方的数据库课程中,其中有一节提到了PolarDB for PostgreSQL 可以进行数据压缩,压缩比率非常高100%的数据经过压缩后,只剩下40%。在文章的评论区,我记得有一个同志问,这个会不会影响PostgreSQL的运行效率。

是的,其实不光他担心,传统DBA也担心这个问题,在POSTGRESQL中我们可以通过很多的方法对数据进行压缩,但这些方法都有一个问题,对CPU的消耗。所以提出这个问题的同志的担心是有必要的,但这里需要说明PolarDB for PostgreSQL的压缩是硬件压缩,也就是磁盘本身有压缩的功能,基于存算分离的设计和特性,这里磁盘的压缩和计算CPU是无关的。

但我们必须要经过测试才能证明这点,这里我们准备了两个数据库都是PolarDB for PostgreSQL 14,其中一个我们开启压缩,一个不开启压缩,其他的配置和功能完全一致。

主机是个人账号购买,消费
主机是个人账号购买,消费

主机是个人账号购买,消费

压测很简单还是通过撰写一个测试的脚本来完成。

代码语言:javascript
代码运行次数:0
运行
复制
-- 清理旧表
DROP TABLE IF EXISTS table3;
DROP TABLE IF EXISTS table2;
DROP TABLE IF EXISTS table1;

-- 创建表结构
CREATE TABLE table1 (
    id SERIAL PRIMARY KEY,
    name TEXT,
    value INT
);

CREATE TABLE table2 (
    id SERIAL PRIMARY KEY,
    table1_id INT REFERENCES table1(id),
    description TEXT
);

CREATE TABLE table3 (
    id SERIAL PRIMARY KEY,
    table2_id INT REFERENCES table2(id),
    tag TEXT
);
代码语言:javascript
代码运行次数:0
运行
复制
DO $$
DECLARE
    i INT := 1;
    start_time TIMESTAMP;
    end_time TIMESTAMP;
BEGIN
    RAISE NOTICE '开始插入 table1';
    start_time := clock_timestamp();
    WHILE i <= 1000000 LOOP
        INSERT INTO table1(name, value) VALUES ('name_' || i, i);
        i := i + 1;
    END LOOP;
    end_time := clock_timestamp();
    RAISE NOTICE 'table1 插入耗时: % 秒', EXTRACT(SECOND FROM end_time - start_time);

    i := 1;
    RAISE NOTICE '开始插入 table2';
    start_time := clock_timestamp();
    WHILE i <= 1000000 LOOP
        INSERT INTO table2(table1_id, description) VALUES ((random()*999999 + 1)::INT, 'desc_' || i);
        i := i + 1;
    END LOOP;
    end_time := clock_timestamp();
    RAISE NOTICE 'table2 插入耗时: % 秒', EXTRACT(SECOND FROM end_time - start_time);

    i := 1;
    RAISE NOTICE '开始插入 table3';
    start_time := clock_timestamp();
    WHILE i <= 1000000 LOOP
        INSERT INTO table3(table2_id, tag) VALUES ((random()*999999 + 1)::INT, 'tag_' || i);
        i := i + 1;
    END LOOP;
    end_time := clock_timestamp();
    RAISE NOTICE 'table3 插入耗时: % 秒', EXTRACT(SECOND FROM end_time - start_time);
END
$$;


代码语言:javascript
代码运行次数:0
运行
复制
DO $$
DECLARE
    i INT := 1;
    start_time TIMESTAMP;
    end_time TIMESTAMP;
BEGIN
    RAISE NOTICE '开始更新 table1';
    start_time := clock_timestamp();
    WHILE i <= 100000 LOOP
        UPDATE table1 SET value = value + 1 WHERE id = (random()*999999 + 1)::INT;
        i := i + 1;
    END LOOP;
    end_time := clock_timestamp();
    RAISE NOTICE 'table1 更新耗时: % 秒', EXTRACT(SECOND FROM end_time - start_time);

    i := 1;
    RAISE NOTICE '开始更新 table2';
    start_time := clock_timestamp();
    WHILE i <= 100000 LOOP
        UPDATE table2 SET description = description || '_u' WHERE id = (random()*999999 + 1)::INT;
        i := i + 1;
    END LOOP;
    end_time := clock_timestamp();
    RAISE NOTICE 'table2 更新耗时: % 秒', EXTRACT(SECOND FROM end_time - start_time);

    i := 1;
    RAISE NOTICE '开始更新 table3';
    start_time := clock_timestamp();
    WHILE i <= 100000 LOOP
        UPDATE table3 SET tag = tag || '_v' WHERE id = (random()*999999 + 1)::INT;
        i := i + 1;
    END LOOP;
    end_time := clock_timestamp();
    RAISE NOTICE 'table3 更新耗时: % 秒', EXTRACT(SECOND FROM end_time - start_time);
END
$$;

代码语言:javascript
代码运行次数:0
运行
复制
DO $$
DECLARE
    i INT := 1;
    start_time TIMESTAMP;
    end_time TIMESTAMP;
    dummy TEXT;
BEGIN
    RAISE NOTICE '开始单表查询 table1';
    start_time := clock_timestamp();
    WHILE i <= 10000 LOOP
        SELECT name INTO dummy FROM table1 WHERE id = (random()*999999 + 1)::INT;
        i := i + 1;
    END LOOP;
    end_time := clock_timestamp();
    RAISE NOTICE 'table1 单表查询耗时: % 秒', EXTRACT(SECOND FROM end_time - start_time);

    i := 1;
    RAISE NOTICE '开始单表查询 table2';
    start_time := clock_timestamp();
    WHILE i <= 10000 LOOP
        SELECT description INTO dummy FROM table2 WHERE id = (random()*999999 + 1)::INT;
        i := i + 1;
    END LOOP;
    end_time := clock_timestamp();
    RAISE NOTICE 'table2 单表查询耗时: % 秒', EXTRACT(SECOND FROM end_time - start_time);

    i := 1;
    RAISE NOTICE '开始单表查询 table3';
    start_time := clock_timestamp();
    WHILE i <= 10000 LOOP
        SELECT tag INTO dummy FROM table3 WHERE id = (random()*999999 + 1)::INT;
        i := i + 1;
    END LOOP;
    end_time := clock_timestamp();
    RAISE NOTICE 'table3 单表查询耗时: % 秒', EXTRACT(SECOND FROM end_time - start_time);

    i := 1;
    RAISE NOTICE '开始多表联查';
    start_time := clock_timestamp();
    WHILE i <= 10000 LOOP
        SELECT t1.name, t2.description, t3.tag
        INTO dummy, dummy, dummy
        FROM table1 t1
        JOIN table2 t2 ON t1.id = t2.table1_id
        JOIN table3 t3 ON t2.id = t3.table2_id
        WHERE t1.id = (random()*999999 + 1)::INT
        LIMIT 1;
        i := i + 1;
    END LOOP;
    end_time := clock_timestamp();
    RAISE NOTICE '多表联查耗时: % 秒', EXTRACT(SECOND FROM end_time - start_time);
END
$$;


下面我将执行的结果进行截图,方便大家比对

1 打开压缩的

PLS4打开压缩
PLS4打开压缩

PLS4打开压缩

2 关闭压缩的

PLS4关闭压缩
PLS4关闭压缩

PLS4关闭压缩

表名

压缩 (s)

不压缩 (s)

差异 (s)

说明

table1

5.172172

5.529172

+0.357

微小浮动

table2

30.73330

30.63361

-0.100

稳定

table3

30.28279

31.89955

+1.617

有波动

压测的数据库性能
压测的数据库性能

压测的数据库性能

不压测的数据库性能
不压测的数据库性能

不压测的数据库性能

数据插入,在数据插入的结果中明显开启压缩的情况CPU消耗要更平稳,而不开启压缩的PolarDB for PostgreSQL CPU突发的消耗会更多。

第二个测试,用大量的UPDATE对两个数据库进行同样的压力测试。

同样的代码
同样的代码

同样的代码

在测试中出现了一个与大部分人想法相反的情况,压缩的PolarDB for PostgreSQL 要比不压缩的IOPS低,也就是执行同样的指令尤其在数据UPDATE的操作中,压缩的PolarDB for PostgreSQL IOPS要更低。

不压缩的 polardb for PG
不压缩的 polardb for PG

不压缩的 polardb for PG

压缩的polardb for postgresql
压缩的polardb for postgresql

压缩的polardb for postgresql

3 最后我们通过多表的查询来对此次的测试压缩和不压缩的性能差别进行一个总结,我们执行同样的查询压测脚本在两个服务器上,同样的数据,同样的查询我们看看相关得到的结果

查询脚本
查询脚本

查询脚本

不压缩查询的速度
不压缩查询的速度

不压缩查询的速度

压缩查询的速度
压缩查询的速度

压缩查询的速度

📊 PostgreSQL 查询耗时对比(单位:秒)

查询类型

表名

压缩后耗时

未压缩耗时

单表查询

table1

12.307233

20.791665

单表查询

table2

37.118749

44.701972

单表查询

table3

37.540800

50.294852

压缩的测试性能图
压缩的测试性能图

压缩的测试性能图

不压缩测试性能图
不压缩测试性能图

不压缩测试性能图

所以那个问PolarDB for PostgreSQL压缩后会性能变差吗,NO NO NO ,经过上面的测试给出的结果是,一定要压缩,压缩后系统又稳定,SQL运行又快,So good !

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-08-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AustinDatabases 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 📊 PostgreSQL 查询耗时对比(单位:秒)
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档