删除 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 中的行数多,那么您可以执行 CTAS 即 create 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 块才能做到这一点。
我有 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 中的行数多,那么您可以执行 CTAS 即 create 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 块才能做到这一点。