sql >> Databáze >  >> RDS >> Oracle

Optimální způsob, jak DELETE zadané řádky z Oracle

Před zodpovězením mých otázek bych to řešil takto:

Minimalizujte počet prohlášení a práce, kterou vydávají v relativním vyjádření.

Všechny scénáře předpokládají, že máte tabulku ID (PURGE_IDS ) odstranit z TABLE_1 , TABLE_2 , atd.

Zvažte použití CREATE TABLE AS SELECT pro skutečně velká smazání

Pokud nedochází k žádné souběžné aktivitě a odstraňujete 30+ % řádků v jedné nebo více tabulkách, nemažte; provést create table as select s řádky, které si chcete ponechat, a vyměňte novou tabulku za starou. INSERT /*+ APPEND */ ... NOLOGGING je překvapivě levné, pokud si to můžete dovolit. I když máte nějakou souběžnou aktivitu, možná budete moci použít předefinování tabulky online k přestavbě tabulky na místě.

Nespouštějte příkazy DELETE, o kterých víte, že nesmažou žádné řádky

Pokud hodnota ID existuje maximálně v jedné ze šesti tabulek, sledujte, která ID jste odstranili – a nepokoušejte se tato ID odstranit z žádné z ostatních tabulek.

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;

a opakujte.

Pokud musíte, spravujte souběžnost

Dalším způsobem je použití smyčky PL/SQL nad tabulkami a vydání příkazu delete s omezením počtu řádků. To je s největší pravděpodobností vhodné, pokud dochází k významnému souběžnému zatížení vkládání/aktualizace/mazání u tabulek, u kterých spouštíte odstraňování.

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. Postgresql:Připojení odmítnuto. Zkontrolujte, že název hostitele a port jsou správné a že správce pošty přijímá připojení TCP/IP

  2. datetime to totalminute v sql

  3. Podmíněný příkaz JOIN SQL Server

  4. jak používat xmltable v oracle?