!!! Od 1.6.2022 nastupuji do Komerční banky tvořit novou digitální banku. Školení se nechci úplně vzdávat, v současnosti přemýšlím nad tím, jak alespoň pár školení za rok uskutečnit. Pokud by mi někdo se školeními chtěl pomoci, tak se mi ozvěte. Na JavaDays opět budu, to si nenechám ujít :-) Teď budu mít v KB hodně práce než si všechno sedne, ale jakmile to nastane, tak hned budu přemýšlet nad tím, jak alespoň pár školení za rok uskutečnit, protože je hromada lidí, které bych opět strašně moc rád viděl a považuji je za přátele. Časem (nejspíš v příštích pár měsících) vytvořím nový blog na separátní doméně a novinky Java a SQL školení dále rozšiřovat nebudu. Pokud se něco změní, tak to dám včas vědět zde na webu a na blogu. !!!

cursor for loop vs. bulk collect forall

publikováno: 4.1.2016

Všude čtu jak je BULK-COLLECT výkonný, tak jsem se rozhodl to změřit. Mám data v jedné tabulce a potřebuji některé z nich získat a uložit je do druhé tabulky.

Vstupní data:

-- 1. create table
create table test_bulk_source (num number); 
create table test_bulk_target (num number);
-- 2. insert test data
declare
  maximum integer := 1000000;
begin
  FOR i IN 1..maximum LOOP
    insert into test_bulk_source values (dbms_random.random);
  END LOOP;
  commit;
end;

 

Mimochodem: nejjednodušší je udělat toto a vyprdnout se na cokoli složitějšího:

-- 3A. copy data using insert ... select statement 
-- (operation took on my computer 0,3 seconds!!!)
declare
  time_start number;
begin
  execute immediate 'truncate table test_bulk_target';
  time_start := dbms_utility.get_time();
  insert into test_bulk_target select num from test_bulk_source 
                               where num > 500000;
  commit;
  dbms_output.put_line('operation took: ' || (dbms_utility.get_time() 
                         - time_start) / 100 || ' seconds');
end;

 

Kdybychom ale potřebovali se záznamem udělat nějakou operaci, kterou v jednom SELECTu nezvládneme, pak bychom to mohli napsat takto:

-- 3B. copy data using for-loop
-- (operation took on my computer 30 seconds!!!)
declare
  time_start number;
begin
  execute immediate 'truncate table test_bulk_target';
  time_start := dbms_utility.get_time();
  for num_rec in (select num from test_bulk_source where num > 500000)
  loop
    insert into test_bulk_target values (num_rec.num);
  end loop;
  commit;
  dbms_output.put_line('operation took: ' || (dbms_utility.get_time() 
                         - time_start) / 100 || ' seconds');
end;

 

Ale skutečně výkonné řešení je toto:

-- 3C. copy data using bulk-collect-forall
-- (operation took on my computer 0,5 seconds!!!)
declare
  time_start number;
  cursor c is select num from test_bulk_source where num > 500000;
  type number_collection is table of number;
  numbers number_collection;
begin
  execute immediate 'truncate table test_bulk_target';
  time_start := dbms_utility.get_time();
  open c;
  fetch c bulk collect into numbers;
  forall i in numbers.first .. numbers.last
    insert into test_bulk_target values(numbers(i));
  close c;
  commit;
  dbms_output.put_line('operation took: ' || (dbms_utility.get_time() 
                         - time_start) / 100 || ' seconds');
end;

Reference

Školení bych doporučil všem lidem, kteří se chtějí dozvědět něco o DB. Na školeni jsem přišel, jako úplný nováček, co se týče práci s DB a odcházel plný dojmů a

Ondřej

Osobně jsem trošku stále váhající, jestli a jak moc SQL použít. Ale určitě hlavní je to, že se teď už tolik nebojím. Je to pro mě začátek dlouhé cesty. Osobně

Robert

Zajímavé školení, které vhodně kombinovalo teorii a praxi.

Ministerstvo financí
Jan


Novinky

9.9.2021: SQL Developer & Remote Debug

22.3.2019: Termíny SQL školení léto 2019
Nové termíny!!!

3.1.2018: Oracle XE 12c nebude, místo toho bude Oracle XE 18c
V roce 2018 nás čeká nová XE verze a nové verzování