Ver Mensaje Individual
  #4 (permalink)  
Antiguo 08/10/2011, 04:20
Avatar de matanga
matanga
 
Fecha de Ingreso: octubre-2007
Ubicación: España
Mensajes: 1.091
Antigüedad: 17 años, 1 mes
Puntos: 85
Respuesta: Ejecutar store procedure en paralelo

No conozco los detalles del procedimiento, pero diría que te estás complicando un poco, el paralelismo que buscas ya lo provee Oracle con Parallel Query en los SELECT, imagina que tienes una tabla muy grande y tienes que recorrer todos los registros, es más eficiente una única sesión haciendo un FULL SCAN a través de múltiples procesos parallel a tener 10 sesiones diferentes ejecutando 10 consultas con un filtro que puede o no usar un índice.

Después, si el proceso modifica datos y no diseñas correctamente las transacciones, puedes terminar en un error por deadlock, algo típico en procesos paralelos que se ejecutan en sesiones diferentes y modifican las mismas tablas. También debes considerar el diseño de los bloqueos, si un proceso tiene un lock sobre una tabla por modificación y tarda en liberar el recurso, el proceso que venga detrás estará en espera hasta que finalice el primero, lo que evita cualquier intento de paralelismo además del costo adicional para el motor en gestionar la espera, esto lo puedes ver en la estadística lockwait.

Por último, las tablas temporales tienen bajo rendimiento si las comparas con las variables de tipo tabla (o colecciones), las dos tienen la posibilidad de almacenar filas, pero las tablas temporales van a disco y están sujetas a transacciones, mientras que las colecciones, al ser tratadas como cualquier otra variable, resuelven todo en memoria.

En general, una buena estrategia es un único proceso que lea muchas filas con parallel, suba rápido las filas a memoria, modifique las filas en variables y finalmente haga los insert en serie.

No se si resuelve tu caso, pero te dejo un código con bulk collect para que veas un ejemplo de como implementar esto.

Código:
create table t1 (id number(8), datos varchar2(30))
/
declare

 cursor c1 is 
  select 1 as id, to_char(1) as datos from all_objects;

 /* tipo de dato tabla con el formato del cursor*/
 type type_t1 is table of c1%rowtype index by pls_integer;
 t type_t1;

begin

 open c1;
 loop

  /* limite de registros por cada bulk collect, esto es para no consumir toda la PGA*/
  fetch c1 bulk collect into t limit 100;
  exit when t.count = 0;

  /* loop con los datos que tengas que procesar*/
  for i in t.first..t.last loop
    insert into t1 (id, datos) values (t(i).id, t(i).datos);
  end loop;
  
 end loop;

end;
/
Saludos