PostgreSQL数据优化——死元组清理

news/2024/7/9 23:12:12 标签: postgresql, 数据库, 运维开发, 性能优化

最近遇到一个奇怪的问题,一个百万级的PostgreSQL表,只有3个索引。但是每次执行insert或update语句就要几百ms以上。经过查询发现是一个狠简单的问题,数据库死元组太多了,需要手动清理。

在 PG 中,update/delete 语句的实现通过 MVCC 机制的多版本链实现。如下图所示,更新一条元组时,会将原来的元组标记,并新增一条元组。后续的事物通过快照来判断元组的可见性。

对于一条已经被更新/删除的元组来说,当这条元组对所有事物都不可见后,它的存在就没有意义了,理应被删除,对于这种元组,我们称之为“死元组”。当一张表有大量更新/删除时,如果不做清理的话,表里面就会积攒很多这样的“死元组”,占用大量的空间,造成表空间膨胀。

一、清理前

  • 查询死元组数量SQL
SELECT
    c.relname 表名,
    (current_setting('autovacuum_analyze_threshold')::NUMERIC(12,4))+(current_setting('autovacuum_analyze_scale_factor')::NUMERIC(12,4))*reltuples AS 自动分析阈值,
    (current_setting('autovacuum_vacuum_threshold')::NUMERIC(12,4))+(current_setting('autovacuum_vacuum_scale_factor')::NUMERIC(12,4))*reltuples AS 自动清理阈值,
    reltuples::DECIMAL(19,0) 活元组数,
    n_dead_tup::DECIMAL(19,0) 死元组数
FROM
    pg_class c 

LEFT JOIN pg_stat_all_tables d

    ON C.relname = d.relname
WHERE
    c.relname ='你要查询的表名'  AND reltuples > 0
    AND n_dead_tup > (current_setting('autovacuum_analyze_threshold')::NUMERIC(12,4))+(current_setting('autovacuum_analyze_scale_factor')::NUMERIC(12,4))*reltuples;

查询结果

  • 此时的数据库插入耗时测试,执行update语句

Affected rows: 1
时间: 1.371s

二、配置自动清理

AUTOVACUUM:自动清理元组。开启自动清理后,PostgreSQL会在合适的时候自动执行VACUUM操作。

-- 查看当前autovacuum的状态
SHOW autovacuum;
 
-- 开启autovacuum
SET autovacuum = on;

三、使用VACUUM手动清理

自动清理,有时候可能由于参数配置,效果不佳。可以使用VACUUM命令手动清理,注意,清理过程中会锁表

VACUUM FULL VERBOSE 模式名.表名;
VACUUM FULL VERBOSE ANALYZE 模式名.表名;

清理效果图
清理后update效果

Affected rows: 1
时间: 0.427s

四、查询历史清理信息

SELECT
    relname 表名,
    seq_scan 全表扫描次数,
    seq_tup_read 全表扫描记录数,
    idx_scan 索引扫描次数,
    idx_tup_fetch 索引扫描记录数,
    n_tup_ins 插入的条数,
    n_tup_upd 更新的条数,
    n_tup_del 删除的条数,
    n_tup_hot_upd 热更新条数,
    n_live_tup 活动元组估计数,
    n_dead_tup 死亡元组估计数,
     last_vacuum 最后一次手动清理时间,
    last_autovacuum 最后一次自动清理时间,
    last_analyze 最后一次手动分析时间,
    last_autoanalyze 最后一次自动分析时间,
    vacuum_count 手动清理的次数,
    autovacuum_count 自动清理的次数,
     analyze_count 手动分析此表的次数,
    autoanalyze_count 自动分析此表的次数,
    ( CASE WHEN n_live_tup > 0 THEN n_dead_tup :: float8 / n_live_tup :: float8 ELSE 0 END ) :: NUMERIC ( 12, 2 ) AS "死/活元组的比例"
FROM
    pg_stat_all_tables
WHERE
    schemaname = 'public'
ORDER BY n_dead_tup::float8 DESC;

清理结果


http://www.niftyadmin.cn/n/5420581.html

相关文章

基于PHP的数字化档案管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的数字化档案管理系统 一 介绍 此数字化档案管理系统基于原生PHP,MVC架构开发,数据库mysql,前端bootstrap。系统角色分为用户和管理员。 技术栈 php(mvc)mysqlbootstrapphpstudyvscode 二 功能 …

Mock.js 基本语法与应用笔记

🌟 前言 欢迎来到我的技术小宇宙!🌌 这里不仅是我记录技术点滴的后花园,也是我分享学习心得和项目经验的乐园。📚 无论你是技术小白还是资深大牛,这里总有一些内容能触动你的好奇心。🔍 &#x…

C#位移运算,位运算

//位运算 与& 或| 非~ 异或^ int x 10; //00001010 int y 5; //00000101 &:逐位进行与运算:1&1 1 1&0 0 0&0 0 int result_and x & y; //0 |:逐位进行或运算&#xff1a…

开发指南003-访问数据库

平台访问数据库采用JPAHibernate,总共有三种方式: 1、通过平台提供JdbcUtils类直接执行SQL Autowired private JdbcUtils jdbcUtils;public int getCount(){try{return jdbcUtils.queryForInt("select count(*) from sdk_example");}catch(E…

[虚拟机保护逆向] [HGAME 2023 week4]vm

虚拟机逆向的注意点: 根基题目来看,这是一道虚拟机保护逆向的题,这里的虚拟机不是传统意义上像VMware 的虚拟机,这里只是一个程序执行了像cpu取指令、执行指令操作,与汇编指令类似,但是这里的指令硬件编码经…

如何在并行超算云上玩转PWmat②:上机实操入门小Tips

3月的每周二下午14:00我们将会在并行直播间为大家持续带来线上讲座。3月5日我们已完成”PWmat特色功能和应用“的在线宣讲,回看视频和PPT已上传至B站”龙讯旷腾“账号内。 本周开始,张持讲师将会带着大家手把手上机教学,计算特定算例&#x…

系统架构30 - 质量属性

质量属性 概念开发期质量属性运行期质量属性 面向架构评估的质量属性质量属性场景描述 软件系统属性包括功能属性和质量属性,软件架构重点关注的是质量属性。架构的基本需求是在满足功能属性的前提下,关注软件系统质量属性。为了精确、定量地表达系统的质…

java数据结构与算法刷题-----LeetCode39. 组合总和

java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846 文章目录 解题思路 此题为216题的前置题,虽然题目整体难度更为…