delete语句不适用于oracle中的查询

r6l8ljro  于 2021-07-24  发布在  Java
关注(0)|答案(2)|浏览(350)

我有一张table BK_178_ABC . 我只想在满足某些条件时在此表上执行delete语句:
我在这张table上的总数是:

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

我有下面这个条件,如果它满足,那么我需要从这个bk\u 178\u 表中删除。所以,我首先计算了要删除的行的总数。所以,我尝试了下面的语句。

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。
我尝试了两个delete语句,但是,它们都给了我错误的计数。因为,我期望的计数是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
所以,我再次重构了上面的代码,尝试了另一个delete语句:

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语句有什么问题?

v7pvogib

v7pvogib1#

您可以按以下方式在中使用:

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)) 
;
8xiog9wr

8xiog9wr2#

您可能希望使用性能更好的不同技术。在您的例子中,您可以使用ctas/truncate/bulk collect,因为您希望删除表中10%以上的行(22024727中的2902563行)。根据我的经验,当您要消除10%以上的行或表,并且数量超过一百万时,这种技术会更快。但是,请注意insert append将锁定表,因为它是一个直接路径操作。
这种技术的近似值是

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行(这很昂贵),而是创建一个包含要保留的行的表,截断原始行,然后使用带有parallel enable的直接路径操作插入回数据。
在createtableaselect(ctas)中,您可以使用提示来强制并行查询,但是由于我不知道您的数据模型以及这些表上有多少索引,所以我没有涉及这一部分@tajesh在include rowid引用中的做法是正确的,它只获取必须删除的行数。
当做

相关问题