PostgreSQL维护——解决索引膨胀和数据死行

news2024/11/15 15:56:29

注意: 本文内容于 2024-09-16 00:40:33 创建,可能不会在此平台上进行更新。如果您希望查看最新版本或更多相关内容,请访问原文地址:PostgreSQL维护——解决索引膨胀和数据死行。感谢您的关注与支持!

我有一张表,为了保障查询的快速响应,我是在必要的字段上建立了索引。该表的数量基数不变,只是每分钟会更新过来一批数据,如此运行了一年之久,目前即使走索引查询,依旧特别慢。

排查主要是由两个现象导致的。

  1. 索引膨胀
  2. 数据死行

这两个现象是如何出现的呢?频繁的进行insert/update/delete就会出现。

一、复现

下面来简单复现一下。

复现步骤

  1. 创建新表、关闭自动vacuum。vacuum如果开启,就会导致死行问题不复现。
  2. 录入样本数据、并创建索引,默认采用btree。我设置的样本数据为2000行。
  3. 执行insert/update/delete操作,执行10000次,并保持最后的数据总量仍然为2000条。
    • insert && delete:删除的数据作为新数据插入
    • update:更新其他数据字段
  4. 分别比较执行前与执行后的索引总量、死行数量。

以上复现步骤,我已经编写了一套脚本。开箱即用。

脚本地址

取其中一套运行结果,如下

大小/操作阶段insert && delete 前insert && delete 后update 前update 后
索引144KB832KB144KB976KB
数据136KB640KB136KB384KB
死行0行9754行0行9850行

2000条数据在频繁进行insert/delete/update之后,就会导致索引异常膨胀,是原数据大小的几倍之多。即使数据的总数未变,占用的数据空间仍然变大,因为数据死行导致的。

这两个问题,都会直接或者间接影响到数据库的查询速率。如果

二、临时解决方案

数据死行与索引膨胀,根源在于PostgreSQL的MVCC(Multi-Version Concurrency Control),有兴趣可以查阅官方文档。

2.1 数据死行

在 PostgreSQL 中,UPDATE 操作不会直接修改原有行,而是生成一条新的行记录,同时将原有行标记为“死行”,但并不会立即删除它。类似于 UPDATE,DELETE 操作不会立即删除数据行,而是将其标记为“死行”,并等待后续的 VACUUM 操作来真正回收空间。因此,频繁的 DELETE 操作也会导致死行积累。

临时解决方式:vaccum

VACUUM 是 PostgreSQL 中的垃圾收集机制,用于回收那些不再使用的“死”行空间,但不会释放表文件大小。它会标记那些不再使用的行,可以被新数据覆盖,操作过程中不会锁表。

-- vacuum整个库
vacuum;
-- vacuum单个表
vacuum 表名;

其中涉及到的查询死行的SQL如下

select n_dead_tup from pg_stat_user_tables where n_dead_tup>0 and relname='test_data';

2.2 索引膨胀

在 PostgreSQL 中,每次执行 UPDATE 或 DELETE 操作时,并不会直接修改或删除原有的记录。

相反,旧的版本(元组)会被标记为“死行”,而新的数据将作为一个新的行版本插入表中。

对于索引字段,原有的索引条目不会立即被删除,而是新建一个指向新数据的索引条目。因此,频繁的 UPDATE 和 DELETE 会导致索引包含大量的过时条目,引发索引膨胀、查询效率降低。

临时解决方式:重建索引

最简单的方式是先删再增

比较方便的方式是reindex,但是该方式会在重建的过程中锁表。

reindex table 表名;
reindex index 索引名;

自从PostgreSQL12开始,reindex支持并行重建索引,不会锁表,但比直接reindex要慢。

reindex table concurrently 表名;
reindex index concurrently 索引名;

其中涉及到的一些查询索引大小的SQL如下

-- 查询表内总数据大小
select pg_table_size('test_data'),pg_size_pretty(pg_table_size('test_data'));

-- 查询表内总索引大小
select pg_indexes_size('test_data'),pg_size_pretty(pg_indexes_size('test_data'));

-- 查询表的总大小,包含数据和索引
select pg_total_relation_size('test_data'),pg_size_pretty(pg_total_relation_size('test_data'));

三、设计层面规避该问题

单表数据量大,创建索引来加速查询效率,同时又要进行增删改数据。使用单表的做法在短时间内,是个轻量快速的好做法,适合敏捷式开发。但是长时间来看,还需要经常的人工维护,或者配置数据库的定时清理机制(又会存在锁表等问题),这并不好。

在大型项目上,以上做法就不太适合了。因此在设计上,可以做读写分离,实现一劳永逸。

  • 专门的写表,不创建索引,用来快速增删改。

  • 专门的读表,创建索引,用来快速查询。读表数据来源于写表,这之间需要设计一套适应当前需求的同步机制。

这套同步机制,根据我当前的需求,主要有两种同步方式。

  1. 批量增量同步:程序上定期将写表中增量的数据,一次性批量更新到读表。周期根据需求设定。
  2. 全量同步:读表增量同步也会存在膨胀的问题,因此可以定期的将备份一张新的全量读表,替换掉原来的读表。

在PostgreSQL中,如果数据量不是特别大,读表不需要单独建表去维护,直接使用物理视图即可,根据周期定时刷新。

物理视图跟逻辑视图的区别

逻辑视图需要在查询视图时,根据视图逻辑实时查询,与原数据表相比不存在数据差异性问题。

物理视图相当于创建了一张临时表并存储到了磁盘,不会自动更新,需要人工维护。

举例物理视图用法

-- 重建物理视图
drop materialized view if exists view_name;
create materialized view view_name AS
select * from test_data;
-- 锁表更新物理视图
refresh materialized view view_name;
-- 并行更新物理视图,首先需要物理视图有唯一键
create unique index unique_id_index ON view_name (id);
refresh materialized view concurrently view_name;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2142627.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python3网络爬虫开发实战(17)爬虫的管理和部署(第一版)

文章目录 一、 Scrapyd 分布式部署1.1 了解 Scrapyd1.2 准备工作1.3 访问 Scrapyd1.4 Scrapyd 的功能1.5 ScrapydAPI 的使用 二、Scrapyd-Client 的使用2.1 准备工作2.2 Scrapyd-Client 的功能2.3 Scrapyd-Client 部署 三、Scrapyd 对接 Docker3.1 准备工作3.2 对接 Docker 四、…

一款自动对杂乱文件进行整理和分类的AI工具--FileNeatAI

不知道大家有没有这样的痛点,面对自己的下载目录或者文档目录,总是下载了一堆文件,当某天看着这些文件夹想整理和分类的时候,又或者自己工作的时候,面对一堆工作上的文件,却不知道该分在那个分类里&#xf…

时序约束进阶三:Create_clock与Create_Generated_Clock详解

目录 一、前言 二、生成时钟 2.1 示例设计 2.2 主时钟约束 1)约束对象解析 2)约束到非时钟位置 2.3 生成时钟约束 1)无约束 2)倍频约束 3)生成时钟的主时钟约束不正确 4)使能时钟控制的约束 5&…

CI/CD持续集成和持续交付(git工具、gitlab代码仓库、jenkins)

目录 一 CICD是什么 1.1 持续集成(Continuous Integration) 1.2 持续部署(Continuous Deployment) 1.3 持续交付(Continuous Delivery) 二 git工具使用 2.1 git简介 2.2 git 工作流程 三 部署git …

[数据集][目标检测]车窗状态检测车窗开关检测数据集VOC+YOLO格式299张3类别

数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):299 标注数量(xml文件个数):299 标注数量(txt文件个数):299 标注类别…

动态规划:07.路径问题_珠宝的最大价值_C++

题目链接:LCR 166. 珠宝的最高价值 - 力扣(LeetCode)https://leetcode.cn/problems/li-wu-de-zui-da-jie-zhi-lcof/description/ 一、题目解析 题目: 解析: 有过做前几道题的经验,我们会发现这道题其实就…

OpenAI o1——人工智能推理能力的飞跃,助力高级问题解决

前言 开放人工智能 新模型, OpenAI o1 或草莓,代表了 人工智能。它以 OpenAI 的 GPT 系列等先前模型为基础,并引入了增强的推理能力,从而加深了科学、编码和数学等各个领域的问题解决能力。与主要擅长处理和生成文本的前辈不同&a…

如何在win10Docker安装Mysql数据库?

1.拉取镜像 docker pull mysql 2.查看镜像 使用以下命令来查看是否已安装了 mysql镜像。 3.运行镜像 命令: docker run -p 3306:3306 --name mysql --restartalways --privilegedtrue \ -v /usr/local/mysql/log:/var/log/mysql \ -v /usr/local/mysql/data:/var…

AE电源HPG13150 400V Generator 手侧

AE电源HPG13150 400V Generator 手侧

【模板代码的组织结构与模板的显式实例化和声明】模板代码的组织结构与模板的显式实例化和声明

一、模板的组织结构 之前对于模板,我们都是写在同一个 . c p p .cpp .cpp文件下,那如果我们将模板分开,单独开一个 . h .h .h和 . c p p .cpp .cpp来创建模板,会发生什么? 首先,我们创建一个 m y c l a s…

适合骑行的开放式耳机哪个品牌好?四款开放式蓝牙耳机推荐

骑行时是否有必要佩戴耳机是一个需要权衡安全与便利的问题。因为虽然耳机能提供音乐、导航等功能,但也可能分散注意力,影响骑行安全。而且这也是需要看个人需求决定的,骑行戴耳机的需求是什么,我想大部分人应该就是为了接听电话&a…

大端存储与小端存储的存储方式

目录 1.小端存储方式的解释 2.大端存储方式的解释 3.百度笔试题--判断大端存储还是小端存储 小心!VS2022不可直接接触,否则!没这个必要,方源面色淡然一把抓住!顷刻炼化! 1.小端存储方式的解释 小端存储…

DeDeCMS靶场漏洞复现

打开靶场地址 姿势一:通过文件管理器上传webshell 1.登录后台 dedecms默认的后台登录地址为/dede 2.在附加管理里的文件式管理器中有文件上传 3.上传木马文件 4.访问木马文件 并连接 姿势二:修改模板文件获取webshell 1.点击模板里面的默认模板管理 …

【2025】智慧居家养老服务平台的设计与实现、基于AI的居家养老服务平台、居家养老服务平台开发、智慧养老服务平台设计

博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…

CAS 和 synchronized 的优化过程

🍉 目录 CAS 的实现 CAS 的工作原理 优化过程 CAS 的应用 1) 实现原子类 2)实现自旋锁 CAS 的 ABA 问题 synchronized 的 原理 synchronized 基本特点 加锁工作过程 其他优化操作 1. 锁消除 2. 锁粗化 CAS(Compare-And-Swap&…

反编译 AndroidManifest.xml文件-android反编译技术

一、安卓打包后目录 想要查看原来版本配置和关联信息,被打包了,这时候需要工具 AXMLPrinter2.jar 二、反编译环境要求 序号软件说明1java电脑得有java环境2AXMLPrinter2.jarapk中xml解析文件 三、反编译指令 java -jar AXMLPrinter2.jar "C:\Us…

腾讯百度阿里华为常见算法面试题TOP100(4):双指针、哈希、滑动窗口

之前总结过字节跳动TOP50算法面试题: 字节跳动常见算法面试题top50整理_沉迷单车的追风少年-CSDN博客_字节算法面试题 目录 双指针 42.接雨水 283.移动零 11.盛最多水的容器 15.三数之和 哈希 1. 两数之和 49.字母异位词分组 128.最长连续序列 滑动窗…

2024 RSTCONCTF re 部分wp

Unknown Architect DIE查看,RISC_V架构,直接交即可 Duke of the Kingdom 附件拖入jadx 比较简单。脚本 Keypad 附件拖入ida。一共四遍check,都比较简单 Pico-Cypher 文本编辑器打开附件 稍微问一问gpt,得知这是micropython&#x…

数据驱动型营销与开源 AI 智能名片 O2O 商城系统的融合发展

摘要:本文探讨了数据驱动型营销在现代商业中的重要性,阐述了其在消费者管理和产品管理方面的作用。同时,引入“开源 AI 智能名片 O2O 商城系统”,分析其如何与数据驱动型营销相结合,为企业提供更精准的营销决策和更高效…

【Matlab 肌电信号分析】

一、数据预处理 1.1 数据读取 使用matlab从rhd文件中读取原始数据,共64个通道。 1.2 数据滤波 使用 60Hz的Notch filter 和150Hz的高通Butterworth滤波器进行降噪 二、波峰提取 > 每个通道分别根据相应的规则提取出波峰、波谷附近的波形。 三、信号聚类 3.1 降…