删除语句不适用于oracle中的查询

Delete statement not working on query in oracle

我有一个tableBK_178_ABC。我只想在满足某些条件时在此 table 上执行删除语句:

我对此 table 的总计数是:

select count(*) from BK_178_ABC; ==>22024727

我有下面这个条件,如果它满足那么我需要从这个BK_178_ABC中删除table.So,我首先计算了总行数是多少deleted.So ,我试过下面的语句。

SELECT Count(*)                                    
FROM
BK_178_ABC  a
    LEFT JOIN
        (SELECT * FROM xyz WHERE UPPER(type) = 'MOOV' AND UPPER(buyer) = 'KERA') gr
    ON
        SubStr (a.PS_UNIQUE_ID,-8)  = gr.SOURCEID
    LEFT JOIN
        (SELECT * FROM xyz WHERE UPPER(type) = 'MOOV' AND UPPER(buyer) = 'KERA') gr2
    ON
        a.GROUP_NBR   = gr2.SOURCEID
WHERE EXISTS
(
  SELECT 1 FROM droptable drp
  WHERE
    COALESCE(gr.ROLLUPGROUPID, gr2.ROLLUPGROUPID, SubStr(a.ps_unique_id,-8))=drp.groupid
);

所以,要删除的计数是:2902563.

我尝试了两个删除语句,但是它们都给了我错误的 count.Since,我的预期计数是 2902563,但我没有得到正确的结果。

DELETE FROM bk_178_abc     WHERE  EXISTS (SELECT 1 
               FROM   bk_178_abc a 
                      LEFT JOIN (SELECT * 
                                 FROM   xyz 
                                 WHERE  Upper(type) = 'MOOV' 
                                        AND Upper(buyer) = 'KERA') gr 
                             ON Substr (a.ps_unique_id, -8) = gr.sourceid 
                      LEFT JOIN (SELECT * 
                                 FROM   xyz 
                                 WHERE  Upper(type) = 'MOOV' 
                                        AND Upper(buyer) = 'KERA') gr2 
                             ON a.group_nbr = gr2.sourceid 
               WHERE  EXISTS (SELECT 1 
                              FROM   droptable drp 
                              WHERE  COALESCE(gr.rollupgroupid, 
                                     gr2.rollupgroupid, 
                                     Substr(a.ps_unique_id, -8)) = drp.groupid)) 
; 

它清空了整个 table,因为我看到删除的总数是:22024727

所以,我再次重构了上面的代码,尝试了另一个删除语句:

 DECLARE
    
          begin
            DELETE FROM BK_178_ABC  a WHERE EXISTS (SELECT 1 FROM (SELECT * FROM xyz WHERE UPPER(type) = 'MOOV' AND UPPER(buyer) = 'KERA') gr,
             xyz gr2,
            droptable  drp  WHERE   SubStr (a.PS_UNIQUE_ID,-8)  = gr.SOURCEID AND a.GROUP_NBR   = gr.SOURCEID
              AND   COALESCE(gr.ROLLUPGROUPID, gr2.ROLLUPGROUPID, SubStr(a.ps_unique_id,-8))=drp.groupid );  
            Dbms_Output.put_line(SQL%ROWCOUNT);
            END;

我看到行数是 。我的 sql 语句有什么问题?

您可以使用 IN 如下:

DELETE FROM bk_178_abc     WHERE  rowid in (SELECT a.rowid
               FROM   bk_178_abc a 
                      LEFT JOIN (SELECT * 
                                 FROM   xyz 
                                 WHERE  Upper(type) = 'MOOV' 
                                        AND Upper(buyer) = 'KERA') gr 
                             ON Substr (a.ps_unique_id, -8) = gr.sourceid 
                      LEFT JOIN (SELECT * 
                                 FROM   xyz 
                                 WHERE  Upper(type) = 'MOOV' 
                                        AND Upper(buyer) = 'KERA') gr2 
                             ON a.group_nbr = gr2.sourceid 
               WHERE  EXISTS (SELECT 1 
                              FROM   droptable drp 
                              WHERE  COALESCE(gr.rollupgroupid, 
                                     gr2.rollupgroupid, 
                                     Substr(a.ps_unique_id, -8)) = drp.groupid)) 
; 

您可能想要使用性能更好的不同技术。在您的情况下,您可以使用 CTAS/TRUNCATE/BULK COLLECT,因为您想要删除 table(2902563 of 22024727)中超过 10% 的行。根据我的经验,当你想要消除超过 10% 的行或你的 table,并且数字超过一百万时,这种技术会更快。但是,请注意 INSERT APPEND 将锁定 table,因为它是直接路径操作。

此技术的近似值是

alter session enable parallel dml ;

alter session enable parallel ddl ;

alter session force parallel query ;

create table res_bk_178_abc parallel compress  
for 
select * FROM bk_178_abc   WHERE  rowid in (SELECT a.rowid
               FROM   bk_178_abc a 
                      LEFT JOIN (SELECT * 
                                 FROM   xyz 
                                 WHERE  Upper(type) = 'MOOV' 
                                        AND Upper(buyer) = 'KERA') gr 
                             ON Substr (a.ps_unique_id, -8) = gr.sourceid 
                      LEFT JOIN (SELECT * 
                                 FROM   xyz 
                                 WHERE  Upper(type) = 'MOOV' 
                                        AND Upper(buyer) = 'KERA') gr2 
                             ON a.group_nbr = gr2.sourceid 
               WHERE  EXISTS (SELECT 1 
                              FROM   droptable drp 
                              WHERE  COALESCE(gr.rollupgroupid, 
                                     gr2.rollupgroupid, 
                                     Substr(a.ps_unique_id, -8)) = drp.groupid)) ;
                                     
truncate table bk_178_abc reuse storage;

insert /*+append parallel(a) */ into bk_178_abc a select /*+parallel(b) */ * from res_bk_178_abc b; 

commit;

drop table res_bk_178_abc purge; 

基本上,在这种情况下,我没有删除近 300 万行或 22 ,这很昂贵,我创建了一个 table 包含我想保留的行,截断原始行,然后插入回使用具有并行启用的直接路径操作的数据。

在 create table as select (CTAS) 中,您可以使用提示来强制并行查询,但因为我不知道您的数据模型以及您在那些 tables,我没有碰那部分。 @Tajesh 正确地包含了 rowid 引用,以仅获取必须删除的行数。

此致