【深入探讨PostgreSQL:彻底删除数据并释放索引空间】——让数据库空间管理更高效!

ops/2024/12/12 3:59:16/

全文目录:

    • 开篇语
    • 前言 🌟
    • 📜 目录
    • 1. DELETE真的删除了吗? 🤔
    • 2. 删除数据后如何释放索引空间? 📉
      • 2.1 VACUUM 🧹
      • 2.2 VACUUM FULL 🧹💯
      • 2.3 REINDEX 重新索引 🔄
    • 3. 示例演示:释放索引空间的具体操作 💻
      • 3.1 准备数据
      • 3.2 删除部分数据
      • 3.3 使用 VACUUM FULL 释放空间
    • 4. 拓展知识:VACUUM 与 VACUUM FULL的区别 🧹
    • 5. 总结与最佳实践 🎉
      • 总结
      • 最佳实践
    • 文末

开篇语

哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云/阿里云/华为云/51CTO;欢迎大家常来逛逛

  今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。

  我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。

小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!

前言 🌟

在日常的数据库管理中,你是否遇到过这样的情况:删除了大量数据后,发现磁盘空间并没有减少?或者,数据删除后,索引占用的空间依旧庞大,影响了查询效率。这是因为在PostgreSQL中,DELETE 语句虽然删除了数据,但索引的存储空间不会自动释放。这篇文章将带你深入探讨如何在删除数据时同时释放索引空间,从而优化数据库的存储与查询效率。


📜 目录

  1. DELETE真的删除了吗? 🤔
  2. 删除数据后如何释放索引空间? 📉
  3. 示例演示:释放索引空间的具体操作 💻
  4. 拓展知识:VACUUM 与 VACUUM FULL的区别 🧹
  5. 总结与最佳实践 🎉

1. DELETE真的删除了吗? 🤔

在PostgreSQL中,当你执行 DELETE 操作时,数据实际上并没有真正从磁盘中消失。而是被标记为“已删除”,等待后台的清理进程(VACUUM)来回收空间。这种机制主要是为了支持MVCC(多版本并发控制),以确保在高并发环境中能为各个事务提供一致的数据视图。

不过呢,索引的数据块不会自动回收,即使索引指向的行数据被标记为删除,索引块仍然存在!这意味着,如果不进行额外操作,索引会占据越来越多的空间,导致数据库性能下降。


2. 删除数据后如何释放索引空间? 📉

要想彻底释放索引所占的空间,最常用的方式是使用VACUUM命令来清理无效数据。PostgreSQL中有以下几种常用的清理方式:

2.1 VACUUM 🧹

VACUUM 是PostgreSQL内置的清理命令,用来回收被标记为“已删除”数据的存储空间。但要注意的是,普通的 VACUUM 操作仅仅是回收被删除数据的空间,索引空间不会自动回收

VACUUM table_name;

2.2 VACUUM FULL 🧹💯

如果你不仅想释放数据空间,还要释放索引空间,那么可以使用**VACUUM FULL。这个命令会重建表和索引**,从而释放未使用的磁盘空间。不过,VACUUM FULL会持有表的排他锁,操作期间表将不可写入,因此不适合频繁操作的大表。

VACUUM FULL table_name;

2.3 REINDEX 重新索引 🔄

REINDEX 是用于重建索引的命令。在删除大量数据后,索引仍会残留大量空闲块,而执行REINDEX命令可以清理这些空闲块,释放不再使用的空间。可以选择单个索引进行重建,也可以重建整个表的所有索引。

-- 重建指定索引
REINDEX INDEX index_name;-- 重建表的所有索引
REINDEX TABLE table_name;

注意REINDEXVACUUM FULL 一样,可能会对性能造成一定的影响,因此需要选择在业务低峰期操作。


3. 示例演示:释放索引空间的具体操作 💻

下面我们来演示一下删除数据并释放索引空间的完整流程。假设我们有一张员工信息表employees,其中包含大量数据和索引。

3.1 准备数据

首先,创建employees表,并插入一些数据。

CREATE TABLE employees (id SERIAL PRIMARY KEY,name VARCHAR(100),department VARCHAR(50)
);-- 插入10000条数据
INSERT INTO employees (name, department)
SELECT 'Employee ' || i, 'Dept' || (i % 10)
FROM generate_series(1, 10000) AS i;

创建一个索引来加速基于department字段的查询:

CREATE INDEX idx_department ON employees(department);

3.2 删除部分数据

接下来,删除部门编号为Dept5的所有员工记录。

DELETE FROM employees WHERE department = 'Dept5';

这时,可以发现数据被删除了,但索引占用的空间并没有减少。

3.3 使用 VACUUM FULL 释放空间

执行VACUUM FULL来清理表和索引空间。

VACUUM FULL employees;

使用 VACUUM FULL 后,可以通过查看表的存储空间使用情况,确认索引和表空间都得到了释放。可以执行如下查询来查看表和索引的大小:

SELECT pg_size_pretty(pg_total_relation_size('employees')) AS total_size,pg_size_pretty(pg_indexes_size('employees')) AS index_size;

这样,我们就成功释放了索引所占用的空间。


4. 拓展知识:VACUUM 与 VACUUM FULL的区别 🧹

  • VACUUM:标记为“已删除”的数据会被清理,释放存储空间,但并不会收缩索引,也不会减小表的物理大小。适合日常的维护操作。

  • VACUUM FULL:不仅会清理已删除的数据,还会进行物理表的重组和索引空间的释放。该命令适用于磁盘空间紧张的情况,但会锁住表,期间无法进行写操作,因此应避免频繁使用。

  • AutoVacuum:PostgreSQL还提供了AutoVacuum自动清理机制,通常会自动运行VACUUM。不过,该机制不会执行VACUUM FULL,因此无法主动释放索引空间。


5. 总结与最佳实践 🎉

总结

在PostgreSQL中,删除数据并不会自动释放索引空间,需要通过VACUUM FULLREINDEX命令来手动释放。对于频繁执行DELETE操作的表,定期进行索引重建和VACUUM FULL清理,可以避免索引冗余和性能下降。

最佳实践

  1. 定期使用VACUUM:在业务低峰期,定期对表进行VACUUM,防止表膨胀。
  2. 合理使用VACUUM FULL:避免频繁使用VACUUM FULL,对于小表可以适当安排。
  3. 监控表和索引大小:通过pg_indexes_size()pg_total_relation_size()监控表和索引的大小,及时识别并释放无效空间。
  4. 善用AutoVacuum:默认情况下AutoVacuum是开启的,但可以根据需求调整清理频率。

掌握这些方法后,你就可以高效管理PostgreSQL的存储空间,从而提高数据库性能!希望这篇文章对你有所帮助,记得多多实践哦!

… …

文末

好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。

… …

学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!

wished for you successed !!!


⭐️若喜欢我,就请关注我叭。

⭐️若对您有用,就请点赞叭。

⭐️若有疑问,就请评论留言告诉我叭。


http://www.ppmy.cn/ops/141157.html

相关文章

【Kubernetes理论篇】容器集群管理系统Kubernetes(K8S)

Kubernetes集群部署基本管理实战 这么好的机会,还在等什么! 01、Kubernetes 概述 K8S是什么 K8S 的全称为 Kubernetes (K12345678S),PS:“嘛,写全称也太累了吧,写”。不如整个缩写 K8s 作为缩写的结果…

从0到1实现项目Docker编排部署

在深入讨论 Docker 编排之前,首先让我们了解一下 Docker 技术本身。Docker 是一个开源平台,旨在帮助开发者自动化应用程序的部署、扩展和管理。自 2013 年推出以来,Docker 迅速发展成为现代软件开发和运维领域不可或缺的重要工具。 Docker 采…

工具篇:(一)MacOS 下使用 Navicat 管理 MySQL 数据库:详细图文教程与常见问题解决

MacOS 下使用 Navicat 管理 MySQL 数据库:详细图文教程与常见问题解决 在这篇文章中,我将分享如何在 macOS 上使用 Navicat 来管理 MySQL 数据库。这是一份详细的教程,包括 Navicat 的下载、安装、配置以及使用步骤,并附上亲测的…

【Golang】Go语言编程思想(二):函数式编程

函数式编程 函数与闭包 支持函数式编程的语言当中,函数是一等公民,参数、变量、返回值都可以是函数。 以 adder 为例,下例实现了一个函数式编程: package mainimport "fmt"func adder() func(int) int {sum : 0retu…

华纳云:哪些行业会用到大硬盘存储服务器?

大硬盘存储服务器被广泛应用于需要大量数据存储、处理和管理的多个领域。以下是一些典型的应用场景: 1. 数据中心和云计算:数据中心需要为各种服务提供后端支持,包括云存储、虚拟化、数据库管理和备份恢复等。大数据硬盘服务器能够提供必要的…

评估大语言模型(LLM)在分子预测任务能够理解分子几何形状性能

摘要 论文地址:https://arxiv.org/pdf/2403.05075 近年来,机器学习模型在各个领域越来越受欢迎。学术界和工业界都投入了大量精力来提高机器学习的效率,以期实现人工通用智能(AGI)。其中,大规模语言模型&a…

thinkphp框架使用command实现队列功能

背景 ThinkPHP命令行工具持久化运行的应用场景包括:队列处理,定时任务、后台服务等。本次实战是实现队列处理数据。 步骤1 application目录command.php增加 return [app\admin\command\Crud,app\admin\command\Menu,app\admin\command\Install,app\a…

在GITHUB上传本地文件指南(详细图文版)

这份笔记简述了如何在GITHUB上上传文件夹的详细策略。 既是对自己未来的一个参考,又希望能给各位读者带来帮助。 详细步骤 打开目标文件夹(想要上传的文件夹) 右击点击git bash打开 GitHub创立新的仓库后,点击右上方CODE绿色按…