Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Optymalny sposób na USUNIĘCIE określonych wierszy z Oracle

Zanim odpowiem na moje pytania, podejmę to w ten sposób:

Zminimalizuj liczbę oświadczeń i pracę, którą wykonują w ujęciu względnym.

Wszystkie scenariusze zakładają, że masz tabelę identyfikatorów (PURGE_IDS ), aby usunąć z TABLE_1 , TABLE_2 itp.

Rozważ użycie opcji CREATE TABLE AS SELECT w przypadku naprawdę dużych usunięć

Jeśli nie ma jednoczesnej aktywności i usuwasz ponad 30% wierszy w jednej lub kilku tabelach, nie usuwaj; wykonaj create table as select z wierszami, które chcesz zachować, i zamień nową tabelę na starą. INSERT /*+ APPEND */ ... NOLOGGING jest zaskakująco tani, jeśli możesz sobie na to pozwolić. Nawet jeśli masz jakieś równoległe działania, możesz użyć redefinicji tabeli online, aby odbudować tabelę na miejscu.

Nie uruchamiaj instrukcji DELETE, o których wiesz, że nie usuną żadnych wierszy

Jeśli wartość identyfikatora istnieje co najwyżej w jednej z sześciu tabel, śledź, które identyfikatory zostały usunięte – i nie próbuj usuwać tych identyfikatorów z żadnej z pozostałych tabel.

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;

i powtórz.

Zarządzaj współbieżnością, jeśli musisz

Innym sposobem jest użycie pętli PL/SQL nad tabelami, wydając instrukcję usuwania z ograniczeniem do liczby wierszy. Jest to najprawdopodobniej odpowiednie, jeśli występuje znaczne jednoczesne wstawianie/aktualizowanie/usuwanie w tabelach, dla których wykonujesz operacje usuwania.

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. HikariCP:Jakie limity czasu na poziomie bazy danych należy wziąć pod uwagę, aby ustawić maxLifetime dla Oracle 11g

  2. kopiuj z jednej bazy danych do drugiej za pomocą programisty Oracle sql - połączenie nie powiodło się

  3. Formatowanie ciągu UUID bez REGEXP_REPLACE i PL/SQL

  4. Aktualizacja Salesforce z Oracle®

  5. REGEXP_SUBSTR() Funkcja w Oracle