近日,一位运维人员遭遇了Oracle删除语句的困境。
该运维人员需要删除一张表中的部分数据,于是手动编写了一条删除语句:
DELETE FROM test_table WHERE ID IN (SELECT ID FROM test_table WHERE NAME LIKE '%test%');
但是,执行这条语句后发现并没有生效。通过观察日志,发现此时数据库连接已经关闭。此时,运维人员在追查问题的过程中,发现了Oracle删除语句的特殊规则。
Oracle中的DELETE语句并不像其他数据库一样立即执行删除操作,而是会首先将记录标记为DEL,然后通过Oracle的GC机制来删除已经标记为DEL的记录。
但是,当需要删除的数据量比较大时,Oracle的GC机制就会失效,因此,运维人员需要手动执行COMMIT命令,使Oracle立即删除这些被标记为DEL的记录。
DELETE FROM test_table WHERE ID IN (SELECT ID FROM test_table WHERE NAME LIKE '%test%');
-- 手动执行COMMIT命令
COMMIT;
此时,通过上述修改后,运维人员成功删除了表中的部分数据。
需要注意的是,当需要删除的数据量非常大时,直接使用DELETE语句很容易导致数据库长时间处于锁定状态,从而影响其他用户的使用。因此,在删除大量数据时,建议使用truncate命令进行删除:
TRUNCATE TABLE test_table;
Oracle删除语句是一个比较特殊的操作,需要注意的是,一旦执行了DELETE命令,就需要手动执行COMMIT命令来确保删除操作生效。同时,在删除大量数据时,应该尽量使用truncate命令,以避免对数据库的过度负载。