sql >> Database teknologi >  >> RDS >> Oracle

Optimal måde at SLETTE specificerede rækker fra Oracle

Inden mine spørgsmål bliver besvaret, er det sådan her, jeg vil gøre det:

Minimer antallet af erklæringer og det arbejde, de udfører, udstedt i relative termer.

Alle scenarier forudsætter, at du har en tabel med id'er (PURGE_IDS ) for at slette fra TABLE_1 , TABLE_2 osv.

Overvej at bruge CREATE TABLE AS SELECT til virkelig store sletninger

Hvis der ikke er nogen samtidig aktivitet, og du sletter mere end 30 % af rækkerne i en eller flere af tabellerne, skal du ikke slette; udfør en create table as select med de rækker du ønsker at beholde, og skift det nye bord ud med det gamle bord. INSERT /*+ APPEND */ ... NOLOGGING er overraskende billig, hvis du har råd. Selvom du har en vis samtidig aktivitet, kan du muligvis bruge Online Table Redefinition til at genopbygge bordet på stedet.

Kør ikke DELETE-sætninger, som du ved ikke vil slette nogen rækker

Hvis der findes en ID-værdi i højst en af ​​de seks tabeller, så hold styr på hvilke ID'er du har slettet - og prøv ikke at slette disse ID'er fra nogen af ​​de andre tabeller.

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;

og gentag.

Administrer samtidighed, hvis det er nødvendigt

En anden måde er at bruge PL/SQL-looping over tabellerne ved at udstede en rækkebegrænset delete-sætning. Dette er højst sandsynligt passende, hvis der er betydelig indsættelse/opdater/slet samtidig belastning af de tabeller, du kører sletningerne imod.

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. Sqlite3 indsætter ikke flere rækker i rækkefølge

  2. Entity Framework 6 transaktion rollback

  3. Vigtigheden af ​​transaktionslog i SQL Server

  4. Sådan bestemmes det samlede antal åbne/aktive forbindelser i ms sql server 2005