Как быстро удалить огромные строки в таблице оракулов с помощью запроса параллельных сессий - PullRequest
2 голосов
/ 07 июля 2019

Я использую упомянутый запрос, чтобы удалить более 250 миллионов строк из моей таблицы, и это занимает больше времени

Я пробовал с ограничением t_delete до 20000.

По-прежнему происходит медленное удаление.

Пожалуйста, предложите несколько оптимизаций в одном и том же коде, чтобы выполнить мою работу быстрее.

DECLARE
TYPE tt_delete IS TABLE OF ROWID; t_delete tt_delete;
CURSOR cIMAV IS SELECT ROWID FROM moc_attribute_value where id in (select 
id from ORPHANS_MAV);

total Number:=0;
rcount Number:=0;
Stmt1 varchar2(2000);
Stmt2 varchar2(2000);
BEGIN
---    CREATE TABLE orphansInconsistenDelProgress (currentTable 
VARCHAR(100), deletedCount INT, totalToDelete INT);
---    INSERT INTO orphansInconsistenDelProgress (currentTable, 
deletedCount,totalToDelete) values ('',0,0);
Stmt1:='ALTER SESSION SET parallel_degree_policy = AUTO';
Stmt2:='ALTER SESSION FORCE PARALLEL DML';
EXECUTE IMMEDIATE Stmt1;
EXECUTE IMMEDIATE Stmt2;
---   ALTER SESSION SET parallel_degree_policy = AUTO;
---   ALTER SESSION FORCE PARALLEL DML;
COMMIT;

--- MOC_ATTRIBUTE_VALUE

SELECT count(*) INTO total FROM ORPHANS_MAV;
UPDATE orphansInconsistenDelProgress SET currentTable='ORPHANS_MAV', 
totalToDelete=total;
rcount := 0;
OPEN cIMAV;
LOOP
    FETCH cIMAV BULK COLLECT INTO t_delete LIMIT 2000;
            EXIT WHEN t_delete.COUNT = 0;
            FORALL i IN 1..t_delete.COUNT
        DELETE moc_attribute_value WHERE ROWID = t_delete (i);
    COMMIT;
    rcount := rcount + 2000;
    UPDATE orphansInconsistenDelProgress SET deletedCount=rcount;
END LOOP;
CLOSE cIMAV;
COMMIT;
END;
/ 

Ответы [ 2 ]

1 голос
/ 07 июля 2019

Один параллельный запрос Oracle может упростить код и повысить производительность.

declare
    execute immediate 'alter session enable parallel dml';

    delete /*+ parallel */
    from moc_attribute_value
    where id in (select id from ORPHANS_MAV);

    update OrphansInconsistenDelProgress
    set currentTable = 'ORPHANS_MAV', 
    totalToDelete = sql%rowcount;

    commit;
end;
/

В общем, мы хотим либо позволить Oracle разбить задачу на части, либо использовать наши собственные фрагменты. Кажется, что оригинальный код выполняет обе функции: он считывает данные в виде фрагментов, а затем передает каждый блок для дальнейшего разделения на параллельное удаление. Этот подход порождает множество мелких деталей, и Oracle, вероятно, тратит много времени на такие вещи, как координация потоков.

Удаление большого количества строк стоит дорого, потому что нет способов избежать REDO и UNDO. Возможно, вы захотите изучить использование параметров DDL, таких как усечение раздела или удаление и повторное создание таблицы. (Но будьте осторожны при воссоздании объектов, сложно полностью воссоздать сложные объекты. Мы склонны забывать такие вещи, как привилегии и параметры таблиц.)

Настройка параллелизма и больших заданий сложна. Важно использовать лучшие инструменты мониторинга, чтобы гарантировать, что Oracle запрашивает, выделяет и использует правильное количество параллельных процессов и что план выполнения верен. Одним из сильных преимуществ использования одного оператора SQL является то, что вы можете использовать отчеты мониторинга SQL в реальном времени для мониторинга прогресса. Если у вас есть лицензии Diagnostics and Tuning Pack, найдите SQL_ID в GV$SQL и сгенерируйте отчет с помощью select dbms_sqltune.report_sql_monitor('your SQL_ID here');.

0 голосов
/ 07 июля 2019

может использовать SQL TRUNCATE TABLE,

Урезать таблицу быстрее и использовать меньше ресурсов, чем команда DELETE TABLE.

...