streda, 02 júl 2014 13:51 Written by 7164 times
Rate this item
(3 votes)

SQL - Vymazanie väčšieho počtu riadkov z tabuľky.

Ukážeme si jednoduchý príklad, ako sa dá vymazať veľký počet riadkov z tabuľky v celkom krátkom čase. Mnohí začínajúci programátori napíšu:

SQL> DELETE FROM TEMPTABLE WHERE ID BETWEEN 1000000 AND 3000000;
SQL> COMMIT;

a hotovo.
Áno, príkaz je platný a syntakticky správny. Problém ale nastane, keď množina riadkov, ktoré chceme vymazať z tabuľky obsahuje v blokoch (menšie jednotky, v ktorých ORACLE databázový server ukladá dáta na disk) rádove desiatky MB,
stovky MB alebo celé GB dát. Vtedy môže trvať spracovanie príkazu aj niekoľko hodín. Ukážeme si preto, ako efektívnejšie vymazať veľký počet riadkov z tabuľky.  Príklad som testoval na databázovom prostredí Oracle 11g.

Príklad:
Chceme vymazať z tabuľky TEMPTABLE asi 2 milióny záznamov, ktoré môžu zaberať na disku dosť veľký priestor.
Najjednoduchšie je samozrejme napísať a spustiť už spomenutý príkaz hore:

DELETE FROM TEMPTABLE WHERE ID BETWEEN 1000000 AND 3000000;

Ak by sme spustili tento príkaz, netrúfam si napísať, ako dlho by mohol trvať na vašom počítači. Možno rádovo niekoľko hodín.
Zvolíme trochu iný postup.

Predpoklady:

Užívateľ musí mať nagrantované práva na vytváranie a mazanie tabuliek, práva na pridávanie dát do "tablespace", kde sa nachádza tabuľka, v ktorej vymažeme riadky.
Databáza je v archívnom móde (nie je podmienkou). Treba mať v tabuľkovom priestore, v ktorom sa tabuľka nachádza dosť voľného miesta na vytvorenie kópie aktuálnej tabuľky.

1. Najprv si vytvoríme kópiu aktuálnej tabuľky (ktorá bude prázdna) - _TEMPTABLE.

SQL> CREATE TABLE _TEMPTABLE
     TABLESPACE TEMPTABLESPACE
     NOLOGGING
     AS SELECT * FROM TEMP_TABLE
     WHERE 1=2;



Vytvoríme v tom istom tablespace prázdnu kópiu tabuľky _TEMPTABLE.
Na tabuľke je vypnuté logovanie, z dôvodu rýchlejšieho vkladania záznamov neskôr - NOLOGGING. Všetky DML príkazy na tabuľke, na ktorej je zapnuté logovanie sú logicky pomalšie.
Indexy a "constraints" nie sú na tabuľke vytvorené, vytvoriť ich treba až po celej akcii. Tento stav nám vyhovuje nateraz, lebo akýkoľvek "constraint" alebo index na tabuľke by nám takisto spomaľoval vkladanie riadkov a o to nám teraz práve ide.

2. Premiestnime do novej kópie tabuľky _TEMPTABLE tie dáta, ktoré nemajú byť vymazané.

SQL> INSERT /*+ APPEND PARALLEL(_TEMPTABLE, 2) */ INTO _TEMPTABLE (COLUMN1, COLUMN2, .....)
     SELECT /*+ PARALLEL(TEMPTABLE,4) */ COLUMN1, COLUMN2, .....
     FROM TEMPTABLE
     WHERE  ID<1000000 AND ID> 3000000 /* podmienka, ktorá vyberie riadky, ktoré nemajú byť vymazané */
SQL> COMMIT;    

 
V prípade, ze je povolený paralelizmus na DML príkazoch, odporúčam ho v tomto prípade použiť pre zrýchlené vykonanie. V prípade, že paralelizmus na databáze povolený nie je, je možné ho samozrejme v príkaze vynechať.
     
3. Vymažeme pôvodnú tabuľku TEMPTABLE príkazom:

SQL> DROP TABLE TEMPTABLE /* PURGE */;


Ak použijeme klauzulu "PURGE", tak objekt s dátami nebude premiestnený do "RECYCLE BIN" (ak je to povolené) a bude okamžite uvoľnený priestor v danom tabuľkovom priestore.

4. Premenujeme novú tabuľku na jej pôvodný názov.

SQL> RENAME _TEMPTABLE TO TEMPTABLE;

Potom nesmieme zabudnúť samozrejme zapnúť "constraints" plus indexy, ak na pôvodnej tabuľke boli a ak bolo zapnuté logovanie na tabuľke, treba ho tiež samozrejme dodatočne potom zapnúť.
     
Keďže využívame stav s NOLOGGING (DML príkaz sa neloguje do redologov), nie je možné operáciu vrátiť späť. Je vhodné pred takouto akciou mať vytvorenú celkovú kópiu databázy alebo pôvodnú tabuľku nemazať a ponechať si ju do zálohy.

 

S pozdravom.

Last modified on štvrtok, 03 júl 2014 09:40
Alojz Benďák

Autor je administrátor webu a venuje sa programovaniu takmer 23 rokov.

  • prvý kontakt s počítačmi na strednej škole - PMD 1,2,3, PP06, Atari, Sinclair (programovanie v jazyku: strojový kód, basic a pascal):  2 roky
  • na VŠ - jazyky Turbo pascal a Turbo C: 1rok
  • programovanie databázového ekonomického širokoškálneho software v Delphi a C++ Borland (databázy Paradox): 8 rokov v Codex s.r.o. Nitra
  • programovanie webových aplikácií na databázach MySQL a MS SQL server: 1 roky na živnosť (firmy: Hermes Nitra, Schindler v Bratislave)
  • pracoval ako DBA v Homecredit Brno a vo VÚB Bratislava ako vyvojár + optimalizácie v SQL a PL/SQL na Oracle 11g (firma Accenture)
  • programoval programy pre súkromné firmy pre HW na skenovanie povrchov nádrží pre skladovanie tekutých palív (pristroj Leica)
  • momentálne pracuje ako DBA pod Oracle 11g a ako vyvojár vnútropodnikových databázových aplikacií v PHP, SQL, C++, C# a interface v PL/SQL: 11 rokov
  • ďalej programuje s HTML, CSS, Ajax, Javascript, VBA, MS visual C++ a C# malé podporné aplikácie
  • certifikát SQL expert for Oracle 11g   
  • spolupracuje a aktívne učí pre počítačové firmy: Lapis, IVIT v Nitre