数据库delete不释放空间处理方法

本文探讨了因频繁增删操作导致数据库表出现大量碎片的问题及解决方案。介绍了MySQL、Greenplum (gp)、GBase和Oracle数据库中如何通过优化表、回收垃圾、压缩表空间等手段释放磁盘空间并提升查询性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

      最近做项目遇到个问题,数据库实际有效数据才几万行,但是因为该表属于频繁变动的表,单节点实际已经超过30亿行,rowid一直在增加,直接导致表不可用。最后分析下来,是因为delete操作只是将数据标识位删除,并没有整理数据文件,因此在数据文件中留下了碎片,不释放其占用的空间。如果一张表,频繁被insert、delete,且删除的数据没有规律,那么数据就会出现大量的空洞,占用磁盘空间且影响查询性能。

经过网上搜索了解,目前delete删除数据库有两种情况:

1)当DELETE后面跟条件的时候,则就会出现删除数据后,数据表占用的空间大小不会变。

如:delete from table_name where 条件 

2)不跟条件直接delete的时候,清除了数据,同时数据表的空间也会变为0。

如:delete from table_name 

那么,针对这个问题,搜索整理了一些目前常见的数据库处理方法:

1)mysql:使用OPTIMIZE TABLE 指令对表进行优化。
命令语法:OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ...
最简单的:optimize table XXX;
OPTIMIZE TABLE只对MyISAM, BDB和InnoDB表起作用。
注意,在OPTIMIZE TABLE运行过程中,MySQL会锁定表。因此,这个操作一定要在网站访问量较少的时间段进行。

在多数的设置中,根本不需要运行OPTIMIZE TABLE。即使对可变长度的行进行了大量的更新,也不需要经常运行,每周一次或每月一次只对特定的表运行即可。

2)、gp数据库:定期使用Vacuum analyze tablename 回收垃圾和收集统计信息。
该动作会消耗系统一定的资源,引起系统的IO上升,对有一定系统瓶颈来说容易造成堵塞,严重会把GP宕掉,造成数据库瞬断。vacuum只是简单的回收空间且令其可以再次使用,没有请求排它锁,仍旧可以对表读写。
但是在postgresql中VACUUM的效果并不明显,一般都可认为不回收空间,只有vacuum full才会。vacuum full执行更广泛的处理,包括跨块移动行,以便把表压缩至使用最少的磁盘块数目存储。相对vacuum要慢,而且会请求排它锁。
在日常维护中,需要对数据字典定期执行vacuum,可以每天在数据库空闲的时候进行。然后每隔一段较长时间(两三个月)对系统表执行一次vacuum full,这个操作需要停机,比较耗时,大表可能耗时几个小时。reindex:执行vacuum之后,最好对表上的索引进行重建。

3)、gbase数据库:使用alter table XXX shrink space释放空间。

4)、oracle数据库:

如:alter table XXX enable row movement;
      alter table XXX shrink space
注意:shrink table只会针对assm(自动段空间管理)的表有用,否则会报: ORA-10635: Invalid segment or tablespace type。
alter table XXX enable row movement语句会造成引用表tablename_max的对象(如存储过程、包、视图等)变为无效。执行完成后,最好执行一下utlrp.sql来编译无效的对象。



### Oracle 数据库Delete 操作与空间释放的关系及最优解法 在 Oracle 数据库环境中,`DELETE` 和 `TRUNCATE` 是两种常见的清空数据方式。然而它们的行为有所同,特别是在空间管理和性能方面。 #### ### DELETE 操作是否会释放空间 当使用 `DELETE` 命令时,它实际上是一个 DML (Data Manipulation Language) 操作,意味着每一条记录的删除都会被记录到重做日志中,并且会保留回滚段以便于事务失败时可以恢复原始状态[^1]。更重要的是,默认情况下,即使整个的内容都被删除了,分配给该空间通常会立即返回到系统池里供其他对象使用。这是因为 `DELETE` 只标记那些行作为已删除的状态,而是物理上销毁这些区块,除非随后进行了进一步的操作如调整高水位线(HWM)[^2] 或者执行了压缩操作。 #### ### TRUNCATE 方法及其优势 相比之下,`TRUNCATE TABLE` 属于一种 DDL(Data Definition Language) 动作,它可以迅速地将内的所有数据移除,并且几乎总是伴随着空间的有效回收。这是因为它仅消除了所有的行级数据,而且还会重新设定的高水位线至最低水平,使得之前占用的空间得以解放出来让新插入的数据利用[^3]。此外,由于其本质是非日志化的性质(即很少甚至完全没有生成redo entries),所以在大多数情形下要比同等规模下的 `DELETE` 更加高效快捷。 #### ### 实现快速清空并释放空间的最佳实践 为了既彻底清除数据又及时释放关联的存储资源,推荐采取如下措施之一: 1. **直接应用 TRUNCATE** 如前所述,这通常是最快捷也是最简单的途径。只需要注意是否有任何现存的外键参照此,若有则需先解除或暂时禁用相关约束。 ```plsql CREATE OR REPLACE PROCEDURE purge_table(p_tablename IN VARCHAR2) AS BEGIN EXECUTE IMMEDIATE 'TRUNCATE TABLE ' || p_tablename; EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('Error occurred while truncating table.'); END; / ``` 2. **结合 EXPORT/IMPORT 工具重建结构** 若因特殊原因无法施行 `TRUNCATE`(例如存在复杂的触发器或其他依赖项),可考虑导出元信息后删除再依据备份重建。这样做的代价较高但确实能达到目的。 3. **手动降低 HWM 后 COMPACT DATA** 针对某些允许破坏现有架构却仍期望减少内部碎片的情形,可以通过多次小批次删除配合在线段收缩功能达成近似效果: ```plsql ALTER TABLE mytable ENABLE ROW MOVEMENT; ALTER TABLE mytable SHRINK SPACE CASCADE; ``` 以上三种方法各有优劣,在选用前应充分评估各自适应范围以及潜在风险。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值