Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Oracle »

Cursor tarda mucho en ejecutarse

Estas en el tema de Cursor tarda mucho en ejecutarse en el foro de Oracle en Foros del Web. Saludos, Tengo el siguiente problema En un procedimiento utilizo un cursor cuya consulta está compuesta de 30 funciones: select funcion1, funcion2, funcion3, . . . ...
  #1 (permalink)  
Antiguo 31/01/2009, 15:13
toc
 
Fecha de Ingreso: enero-2009
Mensajes: 3
Antigüedad: 15 años, 2 meses
Puntos: 0
Busqueda Cursor tarda mucho en ejecutarse

Saludos,

Tengo el siguiente problema
En un procedimiento utilizo un cursor cuya consulta está compuesta de 30 funciones:

select
funcion1,
funcion2,
funcion3,
.
.
.
funcion30
from dual;

La información solo la inserto en 3 tablas. Probé la consulta del cursor por separado y tarda 45 minutos aproximadamente(este tiempo es correcto por la cantidad de información procesada) pero en el momento de ejecutar el procedimiento este llega a tardar hasta 5 horas, hice un debug al procedimiento y me di cuenta que la demora es cuando hago fetch al cursor, por favor ayudenme con sus sugerencias. Gracias
  #2 (permalink)  
Antiguo 02/02/2009, 08:47
Avatar de matanga  
Fecha de Ingreso: octubre-2007
Ubicación: España
Mensajes: 1.091
Antigüedad: 16 años, 6 meses
Puntos: 85
Respuesta: Cursor tarda mucho en ejecutarse

El fetch de los cursores ya es conocido por ser problemático, hay dos opciones que puedes probar.

Opcion 1. Un insert sin utilizar un cursor, esta es sin dudas, la más rápida.

Código:
create table t1 (id number(8), datos1 varchar2(30))
/
/* insert into con el select con las 30 funciones */
insert into t1
select 1,to_char(1)) from dual
/
Opción 2. En caso que sea necesario un cursor por algún tipo de procesamiento intermedio antes de hacer el insert, está la forma del bulk collect.

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

 /* select con las 30 funciones */
 cursor c1 is 
  select 1 as id, to_char(1) as datos1
  from dual;

 /* 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 que los datos que tengas que procesar*/
  for i in t.first..t.last loop
    insert into t1 (id, datos1) values (t(i).id, t(i).datos1);
  end loop;
  
 end loop;

end;
/
Saludos
  #3 (permalink)  
Antiguo 14/02/2009, 11:41
toc
 
Fecha de Ingreso: enero-2009
Mensajes: 3
Antigüedad: 15 años, 2 meses
Puntos: 0
Respuesta: Cursor tarda mucho en ejecutarse

Muchas gracias por su ayuda, ahora con la ayuda del bulk collect el proceso tarda apenas 35 minutos.
  #4 (permalink)  
Antiguo 28/06/2011, 03:54
 
Fecha de Ingreso: junio-2006
Ubicación: Lima, mi trabajo
Mensajes: 100
Antigüedad: 17 años, 10 meses
Puntos: 0
Respuesta: Cursor tarda mucho en ejecutarse

Hola,
de antemano gracias por las respuestas,
tengo una consulta en oracle que por si sola no demora mucho, 1 seg, pero cuando cuando se la llama por un cursor y hace un fetch into.., fetch bulk collect into, llega a demorar mucho mas, dicen que la query se ejecuta con el primer fetch, entonces la consulta en si deberia demorar lo mismo que el primer fetch, pero no es asi, alguien sabe que puede estar ocurriendo?

saludos



Cita:
Iniciado por matanga Ver Mensaje
El fetch de los cursores ya es conocido por ser problemático, hay dos opciones que puedes probar.

Opcion 1. Un insert sin utilizar un cursor, esta es sin dudas, la más rápida.

Código:
create table t1 (id number(8), datos1 varchar2(30))
/
/* insert into con el select con las 30 funciones */
insert into t1
select 1,to_char(1)) from dual
/
Opción 2. En caso que sea necesario un cursor por algún tipo de procesamiento intermedio antes de hacer el insert, está la forma del bulk collect.

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

 /* select con las 30 funciones */
 cursor c1 is 
  select 1 as id, to_char(1) as datos1
  from dual;

 /* 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 que los datos que tengas que procesar*/
  for i in t.first..t.last loop
    insert into t1 (id, datos1) values (t(i).id, t(i).datos1);
  end loop;
  
 end loop;

end;
/
Saludos
  #5 (permalink)  
Antiguo 28/06/2011, 05:53
 
Fecha de Ingreso: junio-2007
Mensajes: 891
Antigüedad: 16 años, 10 meses
Puntos: 43
Respuesta: Cursor tarda mucho en ejecutarse

Si te manejas con tablas PL, prueba esto, es muy rápido.

--
-- CARGAMOS LOS DATOS EN MEMORIA
--

select *
bulk collect
into MI_TABLA_PL
from MI_TABLA_NORMAL;

--
-- INSERTAMOS EN TABLA_DESTINO
--

FORALL i IN 1..MI_TABLA_PL.COUNT SAVE EXCEPTIONS


INSERT INTO TABLA_DESTINO MI_TABLA_PL(i);

El SAVE EXCEPTIONS indica que si hay algun error siga insertando y se guarde los registros "malos" por si los quieres tratar :

EJEMPLO ( Parece complicado, pero es muy sencillito )

errores := SQL%BULK_EXCEPTIONS.COUNT;
FOR i IN 1 .. errores
LOOP
ORAERR := SQLERRM(-SQL%BULK_EXCEPTIONS(i).ERROR_CODE) ;
iteracion := SQL%BULK_EXCEPTIONS(i).ERROR_INDEX ;
insert into TABLA_ERRORES values MI_TABLA_PL(iteracion);
END LOOP;
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 00:45.