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

Optimizar inserciones y borrados

Estas en el tema de Optimizar inserciones y borrados en el foro de Oracle en Foros del Web. Hola soy Kaly. Antes de nada un saludo a todos los foreros. A ver si me pueden echar una mano pq estoy un poco perdida ...
  #1 (permalink)  
Antiguo 17/02/2014, 10:05
Avatar de kaly_20  
Fecha de Ingreso: febrero-2014
Mensajes: 2
Antigüedad: 10 años, 2 meses
Puntos: 0
Optimizar inserciones y borrados

Hola soy Kaly. Antes de nada un saludo a todos los foreros.

A ver si me pueden echar una mano pq estoy un poco perdida con un procedimiento que tengo que optimizar. La version de oracle sobre la que va a correr el procedimiento es la 11. El procedimiento originalmente tenia declarado un cursor que se recorria registro a registro para realizar inserciones y borrados a partir de los valores obtenidos, el caso es que esto se prolongaba mucho en el tiempo pq la consulta obtenia muchos registros.

Corregirme si me equivoco, pero por lo que he leido es mejor recuperar los resultados de la consulta con la clausula bulk collect junto con un limit de 100 registros, ademas de desactivar disparadores, restricciones e indices de las tablas implicadas. Lo he cambiado y me ha quedado tal que asi:
Código SQL:
Ver original
  1. DECLARE
  2.   c_datos IS(
  3.     SELECT campo1, campo2, campo3 FROM tabla WHERE fecha < ADD_MONTHS(sysdate, -12));
  4.  
  5.   TYPE datos_tt IS TABLE OF tabla%ROWTYPE INDEX BY PLS_INTEGER;
  6.   var_datos datos_tt;
  7.   limit_in  PLS_INTEGER DEFAULT 100;
  8.   contador  INTEGER := 0;
  9. BEGIN
  10.   --SE DESACTIVA TRIGGERS
  11.   ALTER TRIGGER TGR_TABLA_ELIM DISABLE;
  12.   --SE DESACTIVA RESTRICCIONES FOREING KEY
  13.   ALTER TABLE tabla DISABLE CONSTRAINT FK_TABLA;
  14.   ALTER TABLE tabla2 DISABLE CONSTRAINT FK_TABLA2;
  15.   --SE DESACTIVA RESTRICCIONES PRIMARY KEY
  16.   ALTER TABLE tabla DISABLE CONSTRAINT PK_TABLA2;
  17.   ALTER TABLE tabla2 DISABLE CONSTRAINT PK_TABLA;
  18.   --SE DESACTIVA INDICES
  19.   ALTER INDEX IDX_TABLA ON TABLA DISABLE;
  20.   ALTER INDEX IDX_TABLA2 ON TABLA2 DISABLE;
  21.   -- Se inicia proceso de historizacion
  22.   OPEN c_datos;
  23.   LOOP
  24.     FETCH c_datos BULK COLLECT INTO var_datos LIMIT limit_in;
  25.     EXIT WHEN var_datos.COUNT = 0;
  26.     --Se inserta en el historico los registros obtenidos
  27.     FORALL idx IN 1 .. var_datos.COUNT
  28.       INSERT INTO tabla_historico
  29.         (TBL_CLAVE, CAMPO1, CAMPO2, CAMPO3, CAMPO4, FECHA)
  30.       VALUES
  31.         (var_datos(idx).TBL_CLAVE, var_datos(idx).CAMPO1, var_datos(idx).CAMPO2, var_datos(idx).CAMPO3,
  32.          var_datos(idx).CAMPO4, var_datos(idx).FECHA);
  33.     --Se inserta en el historico 2 los registros de la tabla2 que coincidan con los obtenidos
  34.     FORALL idx IN 1 .. var_datos.COUNT
  35.       INSERT INTO tabla2_historico
  36.         (TBL_CLAVE, CAMPO7, CAMPO8, FECHA)
  37.         SELECT TBL_CLAVE, CAMPO7, CAMPO8, FECHA FROM tabla2 WHERE TBL_CLAVE = var_datos(idx).TBL_CLAVE;
  38.     --Se eliminan los registros de tabla2 insertados en tabla2_historico
  39.     FORALL idx IN 1 .. var_datos.COUNT
  40.       DELETE FROM tabla2 WHERE TBL_CLAVE = var_datos(idx).TBL_CLAVE;
  41.     --El trigger desactivado insertaba los registros eliminados en esta tabla, se hace aqui:
  42.     FORALL idx IN 1 .. var_datos.COUNT
  43.       INSERT INTO TABLA_ELIM (TBL_CLAVE, FECHA) VALUES (var_datos(idx).TBL_CLAVE, SYSDATE);
  44.     --Se eliminan registros obtenidos
  45.     FORALL idx IN 1 .. var_datos.COUNT
  46.       DELETE FROM SGCA2.TABLA WHERE TBL_CLAVE = var_datos(idx).TBL_CLAVE;
  47.     --Se confirma transaccion cada 3000 registros
  48.     contador := contador + var_datos.COUNT;
  49.     IF MOD(contador, 3000) THEN
  50.       COMMIT;
  51.     END IF;
  52.   END LOOP;
  53.   COMMIT;
  54.   CLOSE c_datos;
  55.   --Se elimina registros de la tabla5 anteriores a 24 meses
  56.   num := 0;
  57.   BEGIN
  58.     LOOP
  59.       DELETE FROM tabla5
  60.        WHERE FECHA < ADD_MONTHS(sysdate, -24)
  61.          AND ROWNUM < 3000;
  62.       num := num + SQL%ROWCOUNT;
  63.       EXIT WHEN SQL%ROWCOUNT < 2999;
  64.       COMMIT;
  65.     END LOOP;
  66.     COMMIT;
  67.   END;
  68.   --SE ACTIVA TRIGGERS
  69.   ALTER TRIGGER TGR_TABLA_ELIM ENABLE;
  70.   --SE ACTIVAN RESTRICCIONES
  71.   ALTER TABLE tabla ENABLE NOVALIDATE CONSTRAINT PK_TABLA2;
  72.   ALTER TABLE tabla2 ENABLE NOVALIDATE CONSTRAINT PK_TABLA;
  73.   ALTER TABLE tabla ENABLE NOVALIDATE CONSTRAINT FK_TABLA;
  74.   ALTER TABLE tabla2 ENABLE NOVALIDATE CONSTRAINT FK_TABLA2;
  75.   --SE ACTIVA INDICES
  76.   ALTER INDEX IDX_TABLA ON TABLA REBUILD;
  77.   ALTER INDEX IDX_TABLA2 ON TABLA2 REBUILD;
  78. EXCEPTION
  79.   WHEN OTHERS THEN
  80.     DBMS_OUTPUT.PUT_LINE(SQLCODE || ' - ' || SQLERRM);
  81.     ROLLBACK;
  82. END;

Las dudas que tengo son las siguientes:


1. Que es mejor utilizar en el FORALL: var_datos.COUNT o var_datos.LAST?

2. Las tablas donde se insertan valores no tienen triggers, restricciones ni indices. Las tablas donde se realizan los borrados si. La pregunta es para el borrado tambien es recomendable desactivar indices, triggers y restricciones. Yo los he desactivado y debido a eso he tenido que añadir un ForALL a mayores que me realice lo que hacia el trigger que se activaba en la eliminacion de registros de "tabla".

3. Al final de la coleccion, despues de cerrarla he añadido un loop que elimina de otra tabla que no tiene nada que ver con el cursor registros anteriores a 24 meses, seria mas apropiado realizar con ella un bulk collect??

4. Existe otra forma de realizar este tipo de procedimiento mas eficaz que un cursor o un bulk collect??

Muchas gracias y espero que me puedan dar algo de luz o corregir mi planteamiento.

Etiquetas: fecha, registro, select, tabla
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 08:50.