Oracle
 sql >> база данни >  >> RDS >> Oracle

Оптимален начин за ИЗТРИВАНЕ на определени редове от Oracle

Преди да получа отговор на въпросите ми, бих постъпил по следния начин:

Намалете до минимум броя на изявленията и работата, която вършат, издадени в относително изражение.

Всички сценарии предполагат, че имате таблица с идентификатори (PURGE_IDS ), за да изтриете от TABLE_1 , TABLE_2 и др.

Помислете за използването на CREATE TABLE AS SELECT за наистина големи изтривания

Ако няма едновременна дейност и изтривате 30+ % от редовете в една или повече от таблиците, не изтривайте; изпълнете create table as select с редовете, които искате да запазите, и сменете новата таблица със старата. INSERT /*+ APPEND */ ... NOLOGGING е изненадващо евтино, ако можете да си го позволите. Дори ако имате някаква паралелна дейност, може да сте в състояние да използвате онлайн предефиниране на таблица, за да възстановите таблицата на място.

Не изпълнявайте изрази DELETE, за които знаете, че няма да изтрият редове

Ако идентификационна стойност съществува в най-много една от шестте таблици, следете кои идентификатори сте изтрили – и не се опитвайте да изтриете тези идентификатори от която и да е от другите таблици.

CREATE TABLE TABLE1_PURGE NOLOGGING
AS 
SELECT ID FROM PURGE_IDS INNER JOIN TABLE_1 ON PURGE_IDS.ID = TABLE_1.ID;

DELETE FROM TABLE1 WHERE ID IN (SELECT ID FROM TABLE1_PURGE);

DELETE FROM PURGE_IDS WHERE ID IN (SELECT ID FROM TABLE1_PURGE);

DROP TABLE TABLE1_PURGE;

и повторете.

Управлявайте паралелността, ако трябва

Друг начин е да се използва PL/SQL обикаляне на таблиците, като се издава израз за изтриване с ограничен брой редове. Това най-вероятно е подходящо, ако има значително едновременно натоварване с вмъкване/актуализиране/изтриване на таблиците, срещу които изпълнявате изтриванията.

declare
  l_sql varchar2(4000);
begin
  for i in (select table_name from all_tables 
             where table_name in ('TABLE_1', 'TABLE_2', ...)
             order by table_name);
  loop
    l_sql := 'delete from ' || i.table_name || 
             ' where id in (select id from purge_ids) ' || 
             '   and rownum <= 1000000';
    loop
      commit;
      execute immediate l_sql;
      exit when sql%rowcount <> 1000000;  -- if we delete less than 1,000,000
    end loop;                             -- no more rows need to be deleted!
  end loop;
  commit;
end;


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Функция NVL2() в Oracle

  2. Неявна разлика в преобразуването на потока от данни CAST спрямо ssis

  3. В база данни на Oracle каква е разликата между ROWNUM и ROW_NUMBER?

  4. Възстановяване на файлове на SQL Editor (заявки, процедури) след срив или увисване на Toad For Oracle

  5. Използване на LIKE в клауза IN на Oracle