Mere dataoverførsel takket være "parallelle" PSQL-konstruktioner

Parallel behandling i PSQL forkorter gennemløbstiden for batcharbejde på en maskine med elegant fejlhåndtering.

Invantive PSQL tilbyder nu parallel behandling: den sammensatte sætning parallel ... branch ... end parallel for uensartede blokke side om side, og en parallel-klausul på begge for-loops for ensartet arbejde per række.

parallel-sætningen

Parallel-sætningen gør det muligt at udføre flere PSQL-blokke samtidig, hver indledt med branch og en valgfri mærkat. Et (valgfrit) tal efter parallel angiver det maksimale antal parallelle udførelser, som i:

begin
  parallel 2
  branch <<første>>
    begin
      dbms_output.put_line('første færdig');
    end
  branch <<anden>>
    begin
      dbms_output.put_line('anden færdig');
    end
  end parallel;
end;

Outputtet lyder, hvor rækkefølgen af de to linjer følger færdiggørelsesrækkefølgen og derfor kan variere:

første færdig
anden færdig

Uden save exceptions stopper en fejlagtig gren opstarten af endnu ikke påbegyndte grene; igangværende grene afslutter deres arbejde, og derefter kastes den oprindelige undtagelse igen med navnet på den fejlagtige gren. Eksisterende fejlhåndtering forbliver derfor fungerende.

Med save exceptions udføres alle grene; hvis mindst én mislykkes, følger en samlet undtagelse parallel_error. Via tabelfunktionen dbms_parallel.saved_exceptions() kan de individuelle fejl findes.

Parallelle For-loops

Det er også blevet muligt at behandle resultater fra en for loop parallelt som med:

...
    for r in
    ( select ...
    )
    parallel 8
    save exceptions
    loop
    ...
    end loop;
...

dbms_lock

Synkronisering mellem parallelle grene er muligt med nye funktioner fra dbms_lock (se Nieuwe vergrendelingsfuncties in dbms_lock: request, release, is_acquired en held_locks).

dbms_output

Dbms_output-linjer fra en parallel aktion behandles som en enhed: de bufferes pr. gren og vises som en helhed, når grenen er færdig.

Eksempel: Behandle Fakturaer Parallelt med Genstartbarhed

Følgende eksempel viser mønsteret for finansiel behandling pr. styk: parallelt over rækkerne, prøv alle rækker med save exceptions, opsummér fejl efter afslutning, og genstartbarhed med et statusfilter, så en gentaget kørsel kun fanger resten:

declare
  l_cnt number;
begin
  create or replace table fakturaer@InMemoryStorage
  as
  select 1 faktura_id, 'ÅBEN' status from dual@DataDictionary
  union all
  select 2 faktura_id, 'ÅBEN' status from dual@DataDictionary
  union all
  select 3 faktura_id, 'ÅBEN' status from dual@DataDictionary
  ;
  begin
    for r in
    ( select fct.faktura_id
      from   fakturaer@InMemoryStorage fct
      where  fct.status = 'ÅBEN'
    )
    parallel 8
    save exceptions
    loop
      --
      -- Behandling pr. faktura; faktura 2 mislykkes her med vilje.
      --
      declare
        l_x number;
      begin
        l_x := 1 / (r.faktura_id - 2);
        update fakturaer@InMemoryStorage
        set    status = 'BEHANDLET'
        where  faktura_id = r.faktura_id
        ;
      end;
    end loop;
  exception
    when parallel_error
    then
      l_cnt := 0;
      for f in
      ( select instance
        from   table(dbms_parallel.saved_exceptions())
      )
      loop
        l_cnt := l_cnt + 1;
      end loop;
      dbms_output.put_line(l_cnt || ' faktura ikke behandlet; en næste kørsel fanger resten.');
  end;
  drop table fakturaer@InMemoryStorage;
end;

Outputtet lyder:

1 faktura ikke behandlet; en næste kørsel fanger resten.

Hastighedsbegrænsning

Parallelisme fremskynder især arbejde med ventetid, som opkald til cloudtjenester, og uensartede sektioner side om side. Gennemstrømningen til én platform forbliver begrænset af platformens grænser; disse grænser forbliver under parallel PSQL gældende.

Se også

Se også følgende emner:

Tilgængelighed

Den nye funktionalitet er tilgængelig fra og med udgivelse 27.0.