Оператор удаления не работает с запросом в oracle - PullRequest
0 голосов
/ 09 июля 2020

У меня есть таблица BK_178_ABC. Я хочу выполнить оператор удаления для этой таблицы только тогда, когда выполнено какое-то условие:

Мой общий счет в этой таблице:

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

У меня есть это условие ниже, если оно удовлетворяет, то я необходимо удалить из этой таблицы BK_178_AB C. Итак, я сначала вычислил, какое общее количество строк будет удалено. Итак, я попробовал приведенный ниже оператор.

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 .

Я пробовал два оператора удаления, но оба они дали мне неправильный счет. Так как мое ожидаемое количество 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)) 
; 

Он опустошил всю таблицу, поскольку общее количество удаленных я вижу: 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?

Ответы [ 2 ]

1 голос
/ 09 июля 2020

Вы можете использовать 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)) 
; 
0 голосов
/ 09 июля 2020

Возможно, вы захотите использовать другую технику с более высокой производительностью. В вашем случае вы можете использовать CTAS / TRUNCATE / BULK COLLECT, так как вы хотите удалить более 10% строк в таблице (2902563 из 22024727). По моему опыту, если вы хотите удалить более 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; 

В основном в этом сценарии вместо этого удаления почти 3 миллионов строк или 22, что дорого, я создаю таблицу со строками, которые хочу сохранить, обрезаю исходную и вставляю обратно данные, используя операцию прямого пути с параллельным включением.

В таблице create as select (CTAS) вы можете использовать подсказки для принудительного выполнения параллельного запроса, но, поскольку я не знаю вашу модель данных и сколько у вас индексов в этих таблицах, я не касался этой части. @ Taje sh был прав, включив ссылку rowid, чтобы получить только количество строк, которые необходимо удалить.

С уважением

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...