oracle - 优化 Oracle 的 dup 删除语句

标签 oracle query-optimization

我有 2 个删除语句需要很长时间才能完成。 where子句中的列有多个索引。

什么是重复项? 如果 2 个或多个记录在 id、cid、type、trefid、ordrefid、amount 和 paydt 列中具有相同的值,则存在重复项。

DELETE 删除了大约 100 万条记录。

是否可以以任何方式重写它们以使其更快。

DELETE FROM TABLE1 A WHERE loaddt < (
    SELECT max(loaddt) FROM TABLE1 B
    WHERE 
    a.id=b.id and
    a.cid=b.cid and
    NVL(a.type,'-99999') = NVL(b.type,'-99999') and
    NVL(a.trefid,'-99999')=NVL(b.trefid,'-99999') and
    NVL(a.ordrefid,'-99999')= NVL(b.ordrefid,'-99999') and
    NVL(a.amount,'-99999')=NVL(b.amount,'-99999') and
    NVL(a.paydt,TO_DATE('9999-12-31','YYYY-MM-DD'))=NVL(b.paydt,TO_DATE('9999-12-31','YYYY-MM-DD'))
);

    COMMIT;

DELETE FROM TABLE1 a where rowid > (
    Select min(rowid) from TABLE1 b
    WHERE 
    a.id=b.id and
    a.cid=b.cid and
    NVL(a.type,'-99999') = NVL(b.type,'-99999') and
    NVL(a.trefid,'-99999')=NVL(b.trefid,'-99999') and
    NVL(a.ordrefid,'-99999')= NVL(b.ordrefid,'-99999') and
    NVL(a.amount,'-99999')=NVL(b.amount,'-99999') and
    NVL(a.paydt,TO_DATE('9999-12-31','YYYY-MM-DD'))=NVL(b.paydt,TO_DATE('9999-12-31','YYYY-MM-DD'))
);

commit;

解释计划:

DELETE  TABLE1         

    HASH JOIN 1296491 
    Access Predicates 

        AND 
        A.ID=ITEM_1 
        A.CID=ITEM_2 
        ITEM_3=NVL(TYPE,'-99999') 
        ITEM_4=NVL(TREFID,'-99999') 
        ITEM_5=NVL(ORDREFID,'-99999') 
        ITEM_6=NVL(AMOUNT,(-99999)) 
        ITEM_7=NVL(PAYDT,TO_DATE(' 9999-12-31 00:00:00', 'syyyy-mm-dd hh24:mi:ss')) 

    Filter Predicates 
        LOADDT<MAX(LOADDT)

    TABLE ACCESS  TABLE1     FULL    267904 
    VIEW VW_SQ_1         690385 
    SORT GROUP BY    690385 
        TABLE ACCESS TABLE1      FULL    267904 

最佳答案

table 有多大?如果删除的行数达到 12%,那么您可能会考虑索引。 您能否以某种方式对表进行分区 - 比如按周分区,然后仅扫描实际的一周?

也许这样会更有效。当您使用聚合函数时,oracle 必须遍历所有相关行(在您的情况下为全扫描),但是当您使用exists 时,它会在找到第一次出现时停止。 (当然,当 where 子句中的所有列上都有一个基于函数(因为 NVL)的索引时,查询会快得多)

DELETE FROM TABLE1 A 
WHERE exists (
SELECT 1 
FROM TABLE1 B
WHERE 
A.loaddt != b.loaddt
a.id=b.id and
a.cid=b.cid and
NVL(a.type,'-99999') = NVL(b.type,'-99999') and
NVL(a.trefid,'-99999')=NVL(b.trefid,'-99999') and
NVL(a.ordrefid,'-99999')= NVL(b.ordrefid,'-99999') and
NVL(a.amount,'-99999')=NVL(b.amount,'-99999') and
NVL(a.paydt,TO_DATE('9999-12-31','YYYY-MM-DD'))=NVL(b.paydt,TO_DATE('9999-12-31','YYYY-MM-DD'))
);

关于oracle - 优化 Oracle 的 dup 删除语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12678493/

相关文章:

database - 执行程序 Oracle 11g

mysql - MySQL 按查询转置组是否可优化?

sql - Oracle:如何连接替换变量以形成文件名的一部分?

mysql - 基于 Windows 的 MySQL 分析工具

mysql - 海量查询优化

mysql - 如何加快 MySQL Select Case 查询速度

scala - Spark 数与拍摄和长度

mysql - 使用 SQL 从字段中的任意位置提取分隔的子字符串

java - 指定的 Oracle URL 无效 : OracleDataSource. makeURL

xml - 向 OTRS 发送带有变音符号的 Soap-Request