删除 oracle 中的大记录 sql

Deleting large records in oracle sql

我有 KPI_LOG table,其中包含 600000 记录,并且 table 每次都在增长。我在这个 table 中有 TIME_STAMP 列,它指定了记录的创建时间,我必须从这个 table 中删除超过 2 天的记录。我正在使用以下查询来执行删除:

delete from KPI_LOG where SYSDATE - TIMESTAMP > 2;

但是由于记录的数量太多,如果我在这种情况下使用简单的删除查询会花费很多时间。为此,我正在寻找更快的删除方法,但没有找到任何解决方案。

delete from KPI_LOG where SYSDATE - TIMESTAMP > 2;

如果您要删除的行数比您保留在 table 中的行数多,那么您可以执行 CTAScreate table as select 然后删除旧的可以并重命名新的 table.

请确保您在 timestamp 列上有一个 索引

例如,

CREATE INDEX tmstmp_indx ON KPI_LOG(TIMESTAMP )
/

CREATE TABLE KPI_LOG_NEW 
  AS 
 SELECT * FROM KPI_LOG WHERE TIMESTAMP > SYSDATE -2
/

DROP TABLE KPI_LOG
/

ALTER TABLE KPI_LOG_NEW RENAME TO KPI_LOG
/

确保在新 table.

上创建所有必要的索引和约束

删除行不会重置 HIGH WATERMARK,通过执行 CTAS,您有一个全新的 table。因此,您不必像删除时那样扫描高水位线以下的所有行。

删除记录需要事务日志记录。这是一致性不可或缺的一部分。

这也意味着删除记录远非便宜 - 在这种情况下,当一条语句删除数十万行时,这些行中的每一行都需要先写入事务日志。当您不想删除 所有 条记录时,没有办法解决这个问题。

如果可能,您可以更频繁地调用删除命令 - 删除所花费的总时间不会有太大变化,但每个命令花费的时间会短得多(只要您有适当的索引)。

如果您有一个 ID 作为主键,其数据按升序排列(例如序列),您可以 select 该 ID 列在您要删除的时间间隔内的最小值和最大值。

那么数据库引擎不必比较日期,而是比较主键值!

没有更快的方法,因为主键是聚集索引,这意味着记录在服务器上物理上彼此相邻。

你需要 PL/SQL 块才能做到这一点。