当前位置: 首页 > news >正文

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

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

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

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

一、清理前

  • 查询死元组数量SQL
SELECTc.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) 死元组数
FROMpg_class c LEFT JOIN pg_stat_all_tables dON C.relname = d.relname
WHEREc.relname ='你要查询的表名'  AND reltuples > 0AND 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

四、查询历史清理信息

SELECTrelname 表名,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 "死/活元组的比例"
FROMpg_stat_all_tables
WHEREschemaname = 'public'
ORDER BY n_dead_tup::float8 DESC;

清理结果

相关文章:

  • 前端框架的发展史可以追溯到早期的静态网页时代
  • 寄存器(内存访问)
  • 最短路 算法解析+例题
  • 关于tcp协议
  • 阿里云数据湖存储加速套件JindoData
  • 深度解析:cache的基本概念原理扫盲
  • 3月最新形势分析以及您个人指导结论优化:正式战斗状态的马上拉响
  • 蓝桥杯2023年-阶乘的和(数学推理,C++)
  • css动画和js动画的区别?
  • Web框架开发-web框架
  • 数据处理分类、数据仓库产生原因
  • 数据类型(面向对象)
  • GEE:关于遥感生态指数(RSEI)的若干疑问
  • Unity 3D常用的数据结构
  • C++特性之一:继承
  • [rust! #004] [译] Rust 的内置 Traits, 使用场景, 方式, 和原因
  • “寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
  • 【笔记】你不知道的JS读书笔记——Promise
  • javascript 总结(常用工具类的封装)
  • Mocha测试初探
  • Object.assign方法不能实现深复制
  • Otto开发初探——微服务依赖管理新利器
  • VirtualBox 安装过程中出现 Running VMs found 错误的解决过程
  • 初识 webpack
  • 协程
  • 一份游戏开发学习路线
  • 移动端解决方案学习记录
  • 用Visual Studio开发以太坊智能合约
  • 你对linux中grep命令知道多少?
  • 如何正确理解,内页权重高于首页?
  • ​如何使用ArcGIS Pro制作渐变河流效果
  • #调用传感器数据_Flink使用函数之监控传感器温度上升提醒
  • #数据结构 笔记三
  • #我与Java虚拟机的故事#连载09:面试大厂逃不过的JVM
  • (2024,LoRA,全量微调,低秩,强正则化,缓解遗忘,多样性)LoRA 学习更少,遗忘更少
  • (27)4.8 习题课
  • (4)logging(日志模块)
  • (Redis使用系列) Springboot 使用redis实现接口Api限流 十
  • (WSI分类)WSI分类文献小综述 2024
  • (附源码)springboot课程在线考试系统 毕业设计 655127
  • (附源码)基于SSM多源异构数据关联技术构建智能校园-计算机毕设 64366
  • (机器学习-深度学习快速入门)第三章机器学习-第二节:机器学习模型之线性回归
  • (学习总结16)C++模版2
  • (一)appium-desktop定位元素原理
  • .NET C# 使用 SetWindowsHookEx 监听鼠标或键盘消息以及此方法的坑
  • .net MVC中使用angularJs刷新页面数据列表
  • .Net 代码性能 - (1)
  • .NET(C#) Internals: as a developer, .net framework in my eyes
  • .NET是什么
  • .NET业务框架的构建
  • @RestController注解的使用
  • [20170713] 无法访问SQL Server
  • [Android]How to use FFmpeg to decode Android f...
  • [ASP.NET MVC]如何定制Numeric属性/字段验证消息
  • [AutoSar]BSW_Memory_Stack_004 创建一个简单NV block并调试