全文目录:
- 开篇语
- 前言 🌟
- 📜 目录
- 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
语句虽然删除了数据,但索引的存储空间不会自动释放。这篇文章将带你深入探讨如何在删除数据时同时释放索引空间,从而优化数据库的存储与查询效率。
📜 目录
- DELETE真的删除了吗? 🤔
- 删除数据后如何释放索引空间? 📉
- 示例演示:释放索引空间的具体操作 💻
- 拓展知识:VACUUM 与 VACUUM FULL的区别 🧹
- 总结与最佳实践 🎉
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;
注意:
REINDEX
和VACUUM 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 FULL
或REINDEX
命令来手动释放。对于频繁执行DELETE操作的表,定期进行索引重建和VACUUM FULL
清理,可以避免索引冗余和性能下降。
最佳实践
- 定期使用VACUUM:在业务低峰期,定期对表进行
VACUUM
,防止表膨胀。 - 合理使用VACUUM FULL:避免频繁使用
VACUUM FULL
,对于小表可以适当安排。 - 监控表和索引大小:通过
pg_indexes_size()
和pg_total_relation_size()
监控表和索引的大小,及时识别并释放无效空间。 - 善用AutoVacuum:默认情况下AutoVacuum是开启的,但可以根据需求调整清理频率。
掌握这些方法后,你就可以高效管理PostgreSQL的存储空间,从而提高数据库性能!希望这篇文章对你有所帮助,记得多多实践哦!
… …
文末
好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。
… …
学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!
wished for you successed !!!
⭐️若喜欢我,就请关注我叭。
⭐️若对您有用,就请点赞叭。
⭐️若有疑问,就请评论留言告诉我叭。