Foro de Cobol
Registrate en el Foro de Cobol y Aporta tus experiencias y conocimientos sobre este lenguaje de programacion, con tu ayuda el foro crecera y todos nos podremos beneficiar de los conocimientos de los demas.

Gracias por entrar a COBOLEROS.ES
Síguenos en Twitter

Consideraciones de Diseño DB2

Ver el tema anterior Ver el tema siguiente Ir abajo

Consideraciones de Diseño DB2

Mensaje por Coboler@ el Jue Feb 24, 2011 10:29 pm

MODELO DE DATOS
Fases del Diseño del Modelo de Datos.
En el diseño del modelo de datos podemos distinguir tres etapas:
Modelización: En esta etapa es donde se definen las entidades, los atributos, las claves de las entidades, las relaciones, etc., en esta fase se realiza también el proceso de Normalización del Modelo generalmente en tercera forma normal.
Diseño de Tablas: En esta fase el modelo conceptual de datos se plasma en Tablas DB2. Para realizar esta fase hay que tener en cuenta:
 Integridad Referencial
 Concurrencia
 Operación Continua
Ciclo de vida de los datos: En esta fase del modelo conceptual se define el ciclo de vida de los datos a lo largo del tiempo de funcionamiento de nuestra aplicación. Para realizar esta etapa hay que tener en cuenta:
 Criterios de borrado de datos dentro de las tablas
 Criterios de almacenamiento de datos relevantes dentro de históricos
 Diseño de tablas con información histórica
 Criterios de Backup’s de datos, tanto de información presente como histórica.
Diseño Físico DB2: En esta etapa se definen:
 El tipo de Espacio para Tablas requerido
 Los parámetros de creación del Espacio para Tablas, tamaño, etc.
 Índices a utilizar y parámetros de creación de los mismos, si es único, clúster, etc.
 Distribución física de los datos, dependiendo de la criticidad de los mismos
Validación del Diseño: Una vez se tiene el Modelo de Datos es necesario validarlo junto con el Modelo de Procesos con el fin de analizar el coste de la aplicación.


Consideraciones de Diseño.
Para analizar el coste de una aplicación hay que tener en cuenta:
 Consumo de CPU: Trabajando con DB2 el recurso más utilizado es CPU, su consumo depende de:
o Número de sentencias SQL ejecutadas, este número está directamente relacionado con el Diseño de la Base de Datos. Se puede reducir este número mediante desnormalización del modelo en determinados casos. El coste de cada sentencia DB2 depende también del número de páginas y filas que el DB2 debe recorrer para satisfacer la sentencia. Este coste se relaciona a su vez con el camino que el DB2 elige para buscar los datos, en este caso el factor importante es el diseño de índices. Aunque no se modifique la fila recuperada el coste de la sentencia existe.
o Número de filas ordenadas: En este caso el diseño de un buen índice puede eliminar parte del coste de acceso.
o Número de filas y columnas actualizadas: Este número no depende del diseño de la aplicación sino que es un requisito de la misma.
 Concurrencia: A la hora de realizar el diseño, tanto lógico como físico es necesario pensar detenidamente en la concurrencia que puede existir, tanto On-line con Batch, como la concurrencia de varios procesos simultáneos accediendo a los mismos datos.
 Disponibilidad de los datos: Cada vez es más necesario contar con operación continua, en estos casos la ventana batch no existe y es necesario pensar la forma de realizar los procesos batch sin que molesten al On-line.

Tópicos en el Diseño de Tablas.
Una pregunta típica es: ‘¿Hasta donde es óptimo normalizar un modelo de datos?’.
En el ámbito de modelo conceptual se recomienda llegar hasta Tercera Forma Normal.
Cuando se realiza el Diseño de Tablas, se suele desnormalizar dependiendo de los tipos de procesos que se van a realizar sobre esos datos.
Sí la mayoría de los accesos requieren Join es necesario repasar la normalización del modelo. Este es un caso típico de necesidad de desnormalización. Ahora bien, la desnormalización implica:
 Posibles problemas de Integridad Referencial a la hora de actualizar
 Datos redundantes

Sin embargo se puede mejorar mucho el rendimiento debido a que se reduce el número de accesos.
En general para datos muy actualizados es mejor tener las tablas lo más normalizadas posible, y para datos poco modificados pero muy accedidos es mejor desnormalizar.

Consideraciones en el Diseño de Índices.
El coste de una aplicación dada, con un número dado de accesos a DB2 está directamente relacionado con el coste de cada uno de esos accesos.
Con la aparición en la Versión 4 de DB2 de los índices Type2, se mejora sustancialmente con respecto a los índices Type1 en rendimiento y gestión de bloqueos. En el siguiente punto se relacionan las mejoras conseguidas con los índices Type2.
Como ya se ha mencionado anteriormente, el coste de cada acceso depende principalmente de:
 Número de páginas de datos e índices rastreados por el DB2
 Número de entradas al índice y filas rastreadas por el DB2
 Cantidad de filas ordenadas
 Número de operaciones I/O
Un índice puede mejorar el camino de acceso a los datos de varias maneras:
 Reduciendo el número de páginas y filas rastreadas
 Eliminando procesos de Sort
Ahora bien, el definir un índice tiene otros costes que también es necesario tener en cuenta para valorar sí es mejor o no definirlo:
Un índice encarece:
 Ocupa espacio
 Añade coste por cada operación INSERT y DELETE
 Añade coste por cada actualización que afecte a las columnas del mismo
 Añade tiempo a las utilidades de Load, Recover y Reorg.
 Aumenta la probabilidad de que se produzcan bloqueos y Deadlocks (índices Type1)

El uso de índices debe ser evaluado cuidadosamente en los siguientes casos:
 Tablas de datos muy volátiles que se crean y se borran en un corto espacio de tiempo
 Sobre columnas cuyo ámbito es muy reducido, es decir el conjunto de valores diferentes que puede llegar a tener el índice es muy bajo.

Índices Type2
Las ventajas que nos puede proporcionar utilizar índices de Type2 frente a índices Type1 (el único tipo de índice existente hasta la versión 4 de DB2) las podemos resumir en los siguientes puntos:
 No existe el concepto de subpágina en los índices de Type2
 Las páginas de índices no se bloquean. Un bloqueo sobre la página de datos bloquea la clave índice.
o No hay doble bloqueo en operaciones de Update (bloqueo sobre la página en donde se borra y bloqueo sobre la página donde se inserta)
o No hay bloqueo de páginas durante Split’s.
o Los índices Type2 soportan una alta concurrencia en el bloqueo que se produce en ellos cuando la página de datos ha sido bloqueada. (En algunos casos, esto puede producir contenciones que no se producían con los índices de Type1. Por ejemplo, un Index Scan de un índice Type2 puede requerir bloqueos sobre páginas de datos. Un índice Type1 no necesitaría bloquear ninguna página de datos en un Index Scan. Es por esto por lo que un Index Scan puede provocar contenciones en las páginas de datos con operaciones de actualización).
o Con índices Type2 no se adquieren bloqueos sobre páginas de índice durante modificaciones de la estructura del índice. Una modificación de la estructura se produce con una operación sobre el índice que modifica una parte de la zona NONLEAF del árbol del índice cambiando su estructura. Otras transacciones podrían leer o modificar páginas involucradas en una modificación de estructura.
 En índices de Type2, a no ser que la tabla o Table-Space sea bloqueado de modo X, una operación de DELETE no borra físicamente la entrada en el índice. En su lugar, se pseudo-deletea la entrada en el índice dejándola en la página y se marca para delete. El espacio se mantiene disponible en el índice al menos hasta que se realiza commit del dato, de forma que si se realiza un Rollback, habrá siempre suficiente espacio para reinsertar la entrada borrada y eliminar la necesidad de hacer split de página. Después de realizar commit a la operación de delete, la pseudo-entrada afectada por el commit se borrará físicamente cuando se necesite espacio para un insert o cuando el porcentaje de pseudo-deletes por página supere algún umbral.
 No se producen split’s de última página en índices secuenciales incrementales
 Las filas del índice en la página no tienen por que estar ordenadas
 En índices Type2, los RID’s (records identifiers) asociados a una clave de un índice no único se mantienen en orden ascendente. Este orden ascendente se mantiene para que se puedan realizar búsquedas binarias de un RID en concreto de una forma eficiente. Los RID-map para índices Type-2 pueden contener tantos RID’s como quepan físicamente en una página. No existe el límite de 256 entradas que tenían los índices Type1. A partir de ahora, para borrar un solo RID dentro de la lista de RID’s ya no se requiere una búsqueda secuencial lenta de duplicados que normalmente se extendía a varias páginas LEAF.
 Los índices Type2 utilizan sufijos para truncar las claves que se almacenan en las páginas NONLEAF del índice. Por ejemplo, supongamos que durante un Split de una página Leaf, la clave más alta de la nueva página fuera WXYZ4792 y la última clave de la página previa fuera WXYY5341. Sin utilizar un sufijo para truncar, WXYZ4792 debería ser almacenada como la nueva clave más alta en la página NONLEAF. Utilizando sufijo para truncar, solo WXYZ es almacenado como la nueva clave más alta en la página NONLEAF. Dependiendo del índice, esta técnica proporciona una reducción en el número de niveles del índice y en consecuencia en el número de páginas leídas junto al coste de I/O.
 Hay cuatro tipos de página de índice: páginas de cabecera (header page), páginas de control de espacio (space map page), páginas leaf y páginas nonleaf. Con los índices Type2 los formatos de estas páginas cambian. Por ejemplo, los índices contienen menos páginas space-map pero contienen más información por página.
 No hay índices Type2 de un solo nivel. Un índice de Type2 es creado como mínimo con dos niveles, con una página ROOT que apunta a una página LEAF vacía.
 Con índices Type2, el predicado puede ser evaluado cuando el índice es accedido, sobre todo si todas las columnas en el predicado pertenecen al índice. Si no todas las columnas están presentes en el índice, alguna evaluación podría ser posible cuando el índice es accedido y entonces el predicado es evaluado en el momento de acceder a los datos.
 Utilizar índices Type2 siempre que sea posible. Los índices Type2 proporcionan un aumento en la concurrencia y en el rendimiento. También proporcionan las siguientes funciones que no están disponibles con índices Type1:
o Bloqueo por fila en el Table-space
o Isolation UR para el camino de acceso
o Procesamiento de queries por múltiples tareas paralelas
o Acceso concurrente en particiones lógicas separadas.




PROCESOS ON-LINE.
Consideraciones Previas.
A la hora de diseñar procesos On-line es necesario:
 Minimizar el tiempo de respuesta. Puesto que uno de los principales causantes de este tiempo en aplicaciones DB2 es el acceso a datos, es necesario reducir al mínimo dichos accesos.
 Estudiar detenidamente aquellas transacciones de uso muy frecuente así como las de utilización media pero costosas en sí mismas.
 Estudiar la concurrencia sobre datos, en este punto, un factor a tener en cuenta es el Tamaño y Duración del Bloqueo (Lock) que el DB2 efectúa sobre los datos. Principalmente la recuperación de los datos y el reposicionamiento.

Diseño y Concurrencia.
Los factores que influyen en la concurrencia, entre otros, son;
 Estrategia del bloque DB2.
 Contención por actualización.
 Contención por Insert.
 Generación del número secuencial.

En los siguientes puntos se explica con detalle por que se pueden producir contenciones por actualización, por insert y por generación de número secuencial. Hay que tener en cuenta en estos puntos que cuando se habla de bloqueos en páginas de índices y de subpáginas se refiere siempre a índices de Type 1.

Estrategia de bloqueo DB2:
Acerca de la estrategia de bloqueo del DB2 existe todo un capítulo que la referencia. No obstante, para procesos On-Line, es necesario pensar en bloquear lo menos posible y durante el menor tiempo posible.


Contención por actualización:
Un diseño adecuado puede reducir y/o eliminar este tipo de contenciones.
¿Cómo se produce el bloqueo en la actualización?
Actualización mediante la sentencia DECLARE CURSOR FOR UPDATE:
El DB2 bloquea las siguientes páginas (suponemos que no actualiza campos del índice):
 En el momento de realizar el Fetch:
o La página del índice que contiene la dirección de la página de datos con un tipo ‘U’.
o La página que contiene los datos con tipos ‘U’.
 En el momento que se realiza la sentencia UPDATE:
o La página de datos se bloquea con ‘X’.
o La página del índice no se bloquea con ‘X’ a no ser que se modifiquen campos del índice.
 Se liberan los recursos:
o El bloqueo ‘U’ sobre la página del índice se libera cuando se cierra cursor o cambia página.
o El bloqueo ‘X’ sobre la página de datos se libera en tiempo de COMMIT.
 Cualquier otra transacción puede tener que esperar por:
o Intenta leer (bloqueo ‘S’) la página actualizada antes de que la transacción que la tiene termine.
o Necesite actualizar sobre la misma página o cualquier otra página de datos direccionada por la página del índice que esta bloqueada como ‘U’.

Para datos muy accedidos que no se utilizan no existe ningún problema, ya que los bloqueos en lectura son compatibles además, el acceso puede ser mucho más rápido pues, al ser muy accedida, existe una probabilidad alta que la página necesitada está cargada en el bufferpool.
Si por el contrario, los datos se actualizan, el bloque ‘U’ sobre la página de índices así como el bloqueo en ‘X’ sobre la página de datos puede ser una causa fuerte de contención, sobre todo en tablas de tamaño pequeño o medio. Tablas típicas de:
 Contadores.
 Totales.
 Indicadores.
 Asignación de número secuancial.
 Etc.

Es muy probable que se produzca contención cuando el número de actualizaciones por segundo a una página, supera el tiempo de actualización de la misma. Es decir:
Si se tarda en actualizar la página 0,25 seg. y existen más de tres peticiones de actualización de la página por segundo, seguro que se produce contención.
¿Cómo se resuelve el problema?
 Reducir el tiempo que la subpágina del índice mantiene el bloqueo ‘U’ mediante el cierre del cursor lo antes posible, (después del Fetch y del Update).
 Utilizar especificación del índice para que contenga muchas subpáginas. (En este caso hay que asumir que no existen Inserciones).
 Reducir el tiempo que la página de datos mantiene el bloqueo ‘X’ realizando el update lo más próximo al COMMIT de la transacción.
 Si el camino de acceso a los datos es mediante Table Space Scan, no existe bloqueo del índice, sin embargo el problema de contención puede llegar incluso a ser mayor. Por lo tanto es necesario asegurarse de que el DB2 va a utilizar el índice clúster en este acceso. (En el TS-Scan marca con bloque ‘X’ todas las páginas de datos del Espacio para Tablas desde la primera hasta la página deseada.)
 Dejar una fila por página, sí esto es posible.
 Partir una fila en varias, sí ésta contiene más de un contador.

Contención por Insert:
¿Cómo realiza el DB2 el Insert?
Se supone que la página tiene un índice clúster:
 El DB2 busca espacio próximo e inserta la fila.
 El DB2 actualiza el índice.


Para buscar espacio:
 Busca la página más próxima según clave.
 Si no existe espacio en esa página, busca en las 16 más próximas por encima y por debajo.
 Si aún así no encuentra espacio, busca el primer hueco desde el comienzo del Espacio para Tablas.
 En cualquier caso, sí encuentra espacio en una página y ésta esta bloqueada, el DB2 busca en las siguientes.
Para actualizar el índice, que siempre se mantiene en secuencia lógica:
 Antes de insertar el índice la correspondiente subpágina se bloquea.
 Sí la página de direcciones esta bloqueada, espera.
 Sí la subpágina esta llena, redistribuye las entradas en la página.
 Sí la página esta llena, divide en dos páginas.

1- Insert de claves continuas y ascendentes:
Típico de: Números secuenciales, Fecha y Hora, Timestamp, etc.
Para estos casos es mejor tener poco subdividido el índice, dependiendo del número de actualizaciones.
Este tipo de claves provoca que:
 La concatenación que se provoca en el índice (puesto que el DB2 espera a que la página este libre de bloqueos) sea la causa de un pésimo rendimiento.
 Exista una utilización del espacio para índices pésima, ya que se provocan continuas particiones de páginas de índices.

Posibles soluciones:
Definir el índice basándonos en otra clave, si se puede.
 Utilizar índices multicolumnas, donde la clave ascendente no sea la primera columna. Esta técnica nos puede además permitir utilizar particiones.
 Cambiar la clave ascendente por una clave aleatoria. Esto se puede hacer cuando la clave no es significativa.

Otra técnica puede ser invertir la clave.

Insert en Tablas Vacías.
Estas tablas pueden ser requisitos de aplicación, como tablas de diario, etc.
En estos casos el índice inicialmente sólo tiene una página y se va dividiendo conforme se va insertando, necesitamos un ámbito de bloqueo grande.
No se deben utilizar cuando la actividad sobre ellos es muy alta.
Posibles soluciones:
 Preformatear la tabla.
 Particionar la tabla, si se distribuyen las intersecciones.
 Pensar en una tabla sin índice.
Contención por generación de un número secuencial.
Una clave basada en un número secuencial es única, ordenada (normalmente ascendente) y consecutiva (no existen huecos).
Posibles problemas:
Existen dos problemas potenciales asociados con el uso de números secuenciales en las claves.
 Si se usan para insertar filas en otras tablas.
 La concatenación en la página que mantiene el siguiente número, a la hora de actualizar.

Posibles soluciones:
 Utilizar el Timestamp como número consecutivo. El Timestamp es único, ordenado pero no consecutivo. A veces esto puede satisfacer la necesidad y evita concatenación en la página que contiene el siguiente número. Es una buena alternativa.
 Utilizar una tabla de apoyo, pero esto implica:
o Contenciones en actualización.
o Habría que liberar los bloqueos lo antes posible.
o Si se hiciese COMMIT, podría provocar huecos y esto requiere consumo de recursos adicional.

Evitar DEADLOCKS
Un deadlock se produce cuando un recurso requerido por el programa A esta bloqueado por el programa B, en este caso el programa A intenta esperar a que B lo libere, pero B a su vez esta esperando que A libere otro recurso que él necesita. Frente a esta situación, que el DB2 detecta, uno de los programas debe terminar anormalmente y liberar los recursos para que el otro continúe. Es el DB2 quien decide qué programa debe dar marcha atrás, normalmente elige aquel que haya realizado menos trabajo.
Los casos más comunes que provocan DEADLOCKS son:
 Transacciones que actualizan en las mismas tablas pero en diferente orden.
 Que el DB2 utilice diferentes accesos para canalizar los mismo datos, este es el caso más difícil de evitar.

Las posibles soluciones para evitar este problema son:
 Acceder a recursos críticos lo más tarde posible en el proceso de la transacción.
 Es mejor un Cursor For Update cuando existe la necesidad de leer previa a la actualización, esto es debido a que con este tipo de modificación se bloquea el índice en lectura evitando posibles deadlocks. Esta solución no es posible si se requiere Order By, ya que los bloqueos que utliza el DB2 son incompatibles.

Diseño y eficacia.
El coste de CPU de una Transacción DB2 consta de:
 Coste de Sistema DB2.
o Creación de la conexión THREAD.
o Terminación de la conexión.
o Commit
 Coste de acceso a datos DB2.
o Sentencias SQL de acceso y manipulación de datos.

 Coste de la aplicación.
o Coste de consumo de COBOL.
 Coste CICS.
o Incluye todo el consumo producido por sentencias CICS.

El coste más alto siempre es el producido por el acceso a datos. Hay que procurar que los accesos sean los más óptimos posible, recuperar sólo aquellos datos necesarios y evitar operaciones innecesarias.
El coste Cobol puede llegar a ser importante si no se cuidan mínimamente las técnicas de programación estructurada, eliminando sentencias no necesarias, ejecutar siempre lo mínimo, por ejemplo no introducir en bucles sentencias que se pueden ejecutar sólo una vez, etc.
En el apartado Consideraciones en Construcción se expone una lista de recomendaciones de uso de sentencias SQL.

Diseño y Listas. Técnicas de Reposicionamiento.
La técnica utilizada normalmente es:
 Open de un cursor seleccionando aquellas filas que sean necesarias
 Fetch de cada fila y almacenamiento en Buffer Cics
 Close del cursor
 Cuando la transacción finaliza, se muestra la primera página
Cuando el número de filas que cumplen la condición de búsqueda es elevado, es necesario restringir de alguna manera el número de filas recuperadas en cada ejecución. Esta restricción puede ser:
 En el ámbito funcional, es decir solicitando más información para acotar la búsqueda, desarrollar otro tipo de consulta, etc.
 En el ámbito del programa, recuperando un número determinado de filas por ejecución, y teniendo previsto el reposicionamiento de datos para continuar la búsqueda sólo en caso necesario y a partir de la última fila mostrada
No obstante siempre que se tenga que realizar una lista de consulta el programa debe tener previsto el reposicionamiento, y éste, debe ser óptimo, es decir no recuperar filas que han sido recuperadas en la ejecución previa y discriminándolas por programa, etc.


A continuación se expone una serie de técnicas de reposicionamiento
Técnica 1.

Sí el índice sólo tiene una columna (Campo_1), el cursor quedaría:
EXEC SQL
DECLARE Cursor1_Ejemplo CURSOR FOR
SELECT Campo_1, Campo_2, …….., Campo_n
FROM Tabla_Ejemplo1
WHERE (Condición de Búsqueda)
AND (Campo_1 > &gml.Campo_1)
ORDER BY Campo_1
END-EXEC.
Y en &gml.Campo-1 debe contener la última clave recuperada en caso de reposicionamiento y el valor más bajo en caso de primera vez.
Técnica 2.
Sí el índice contiene las siguientes columnas: Campo_1, Campo_2, Campo_3, los cursores quedarían como:
EXEC SQL
DECLARE Cursor1_Ejemplo CURSOR FOR
SELECT Campo_1, Campo_2, …….., Campo_n
FROM Tabla_Ejemplo1
WHERE (Condición de Búsqueda)
AND (Campo_1 > &gml.Campo_1)
AND (Campo_2 > &gml.Campo_2)
AND (Campo_3 > &gml.Campo_3)
ORDER BY Campo_1, Campo_2, Campo_3
END-EXEC.


EXEC SQL
DECLARE Cursor2_Ejemplo CURSOR FOR
SELECT Campo_1, Campo_2, …….., Campo_n
FROM Tabla_Ejemplo1
WHERE (Condición de Búsqueda)
AND (Campo_1 > &gml.Campo_1)
AND (Campo_2 > &gml.Campo_2)
ORDER BY Campo_1, Campo_2, Campo_3
END-EXEC.
EXEC SQL
DECLARE Cursor3_Ejemplo CURSOR FOR
SELECT Campo_1, Campo_2, …….., Campo_n
FROM Tabla_Ejemplo1
WHERE (Condición de Búsqueda)
AND (Campo_1 > &gml.Campo_1)
ORDER BY Campo_1, Campo_2, Campo_3
END-EXEC.
La programación que trata este tipo de reposicionamiento es más compleja, pero los accesos a DB2 son mucho más efectivos. El tratamiento Cobol sería similar a:
VISION 1:
--------------------------
TRATAMIENTO-CURSOR-1.
**********************************
PERFORM INICIO-TRATAMIENTO-CURSOR-1
PERFORM PROCESO-TRATAMIENTO-CURSOR-1 UNTIL Fin-Mapa
PERFORM FIN-TRATAMIENTO-CURSOR-1.

--------------------------
INICIO-TRATAMIENTO-CURSOR-1.
******************************************
PERFORM ABRIR-CURSOR-1
PERFORM LEER-CURSOR-1
--------------------------

PROCESO-TRATAMIENTO-CURSOR-1.
******************************************
IF Hay-ocurrencias-en Cursor-1
PERFORM MOVER-DATOS-A-MAPA
PERFORM LEER-CURSOR-1
ELSE (*No existen ocurrencias en cursor 1 *)
PERFORM TRATAMIENTO-CURSOR-2
END-IF.
--------------------------
FIN-TRATAMIENTO-CURSOR-1.
******************************************
PERFORM CERRAR-CURSOR-1.

--------------------------

TRATAMIENTO-CURSOR-2.
**********************************
PERFORM INICIO-TRATAMIENTO-CURSOR-2
PERFORM PROCESO-TRATAMIENTO-CURSOR-2 UNTIL Fin-Mapa
PERFORM FIN-TRATAMIENTO-CURSOR-2.

--------------------------
INICIO-TRATAMIENTO-CURSOR-2.
******************************************
PERFORM ABRIR-CURSOR-2
PERFORM LEER-CURSOR-2
--------------------------

PROCESO-TRATAMIENTO-CURSOR-2.
******************************************
IF Hay-ocurrencias-en Cursor-2
PERFORM MOVER-DATOS-A-MAPA
PERFORM LEER-CURSOR-2
ELSE (*No existen ocurrencias en cursor 2 *)
PERFORM TRATAMIENTO-CURSOR-3
END-IF.
--------------------------
FIN-TRATAMIENTO-CURSOR-2.
******************************************
PERFORM CERRAR-CURSOR-2.

--------------------------

TRATAMIENTO-CURSOR-3.
**********************************
PERFORM INICIO-TRATAMIENTO-CURSOR-3
PERFORM PROCESO-TRATAMIENTO-CURSOR-3 UNTIL Fin-Mapa
PERFORM FIN-TRATAMIENTO-CURSOR-3.

--------------------------
INICIO-TRATAMIENTO-CURSOR-3.
******************************************
PERFORM ABRIR-CURSOR-3
PERFORM LEER-CURSOR-3
--------------------------

PROCESO-TRATAMIENTO-CURSOR-3.
******************************************
IF Hay-ocurrencias-en Cursor-3
PERFORM MOVER-DATOS-A-MAPA
PERFORM LEER-CURSOR-3
END-IF.
--------------------------
FIN-TRATAMIENTO-CURSOR-3.
******************************************
PERFORM CERRAR-CURSOR-3.

A continuación se muestra una versión agrupada que da una imagen global del proceso.
VISION 2:
--------------------------
PERFORM ABRIR-CURSOR-1
PERFORM LEER-CURSOR-1
PERFORM UNTIL Fin-Mapa
IF Hay-ocurrencias-en-Cursor-1
PERFORM MOVER-DATOS-A-MAPA
PERFORM LEER-CURSOR-1
ELSE (*No existen ocurrencias en cursor 1 *)
PERFORM ABRIR-CURSOR-2
PERFORM LEER-CURSOR-2
PERFORM UNTIL Fin-Mapa
IF Hay-ocurrencias-en-Cursor-2
PERFORM MOVER-DATOS-A-MAPA
PERFORM LEER-CURSOR-2
ELSE (*No existen ocurrencias en cursor 2 *)
PERFORM ABRIR-CURSOR-3
PERFORM LEER-CURSOR-3
PERFORM UNTIL Fin-Mapa
IF Hay-ocurrencias-en-Cursor-3
PERFORM MOVER-DATOS-A-MAPA
PERFORM LEER-CURSOR-3
END-IF
END-PERFORM
PERFORM CERRAR-CURSOR-3
END-IF
END-PERFORM
PERFORM CERRAR-CURSOR-2
END-IF
END-PERFORM
PERFORM CERRAR-CURSOR-1


Sí fuese necesario declarar más cursores, el tratamiento del resto de los cursores seguiría la misma filosofía.
Es muy importante tratar los cursores en el siguiente orden: del mayor al menor restrictivo y nunca al revés. Este tipo de proceso se recomienda para procesos en los que el volumen de datos a recuperar es elevado. Con esto estamos consiguiendo que el DB2 recupere el menor número posible de datos por ejecución de programa.
Las técnicas mencionadas anteriormente están basadas en el supuesto de acceso por índice Clúster y único. Cuando la clave de acceso no es el índice único, el reposicionamiento es bastante más complejo y es recomendable estudiar cada caso en particular, puesto que es muy arriesgado dar técnicas que se ajusten a la diversidad de condiciones.


PROCESOS BATCH.

Consideraciones Previas
El diseño batch debe realizarse teniendo en cuenta:
 Disponibilidad horaria del proceso batch (Ventana Batch)
 Posibilidad de concurrencia Batch-On-Line
En cualquier caso los objetivos deben ser:
 Reducir el tiempo total de ejecución (Elapsed Time)
 Eliminar los cuellos de botella producidos por operaciones de E/S
 Optimización del consumo de CPU
 Incrementar el paralelismo de procesos cuando se dispone de multiprocesadores
Para lograr estos objetivos hay que tener en cuenta:
 Uso de Prefetch
 Uso de rearranque y reposicionamiento
 Paralelismo y concurrencia

Uso de Prefetch
Prefetch significa lectura de páginas de datos antes de que se necesiten, de manera que cuando el programa los requiera ya estén en el bufferpool del DB2.
Se pueden leer 8, 16, ó 32 páginas en una sóla operación de E/S dependiendo del bufferpool del DB2 asignado.
Los programas de utilidad pueden leer hasta 64 páginas en una sola operación E/S.
El prefetch puede utilizarlo el DB2 tanto para páginas de datos como para páginas de índices.



Existen tres tipos de prefetch:
 SEQUENTIAL PREFETCH: Se invoca siempre que el optimizador estima que al menos ocho páginas van a ser leídas en secuencia del índice cluster. (El optmizador se ejecuta en tiempo de Bind). No se invoca en lecturas directas aunque se recuperen los datos en secuencia del índice cluster.
 LIST PREFETCH: Permite sequential prefetch de páginas de datos cuando estos no se recuperan en orden al cluster sino que lo hace en el orden de otro índice.
 SEQUENTIAL DETECTION: Así es llamado el SEQUENTIAL PREFETCH cuando no ha sido elegido por el optimizador; pero sí es usado en ejecución, porque los datos están siendo accedidos secuencial o casi secuencialmente.
En cualquier caso para saber sí el optimizador ha decidido o no realizar prefetch es necesario analizar el Explain del Plan.

Puntos de Sincronismo y Rearranque
Un factor importante en el diseño batch es el estudio de la necesidad de facilitar puntos de sincronismo.
Se puede decidir utilizar los puntos de sincronismo (Commit) para:
 Aumentar la concurrencia: Una aplicación que actualiza en DB2 genera al menos una Unidad de Trabajo. Una Unidad de Trabajo comienza cuando se actualiza el primer objeto; durante la unidad de trabajo se bloquean los recursos necesarios, esto es ningún otro proceso puede acceder a aquellos datos que estén bloqueados hasta que la unidad de trabajo que los tiene bloqueados finalice. Por lo que para aumentar la concurrencia es necesario reducir la unidad de trabajo.
 Disminuir el tiempo de marcha atrás. Cuando un programa que actualiza DB2 termina anómalamente, es necesario deshacer los cambios realizados en la última unidad de trabajo. Cuanto mayor sea la unidad de trabajo, más actualizaciones puede llegar a hacer, y por lo tanto más habrá que deshacer en caso de terminación anormal. (Es el DB2 quien se encarga de dar marcha atrás a las modificaciones en objetos DB2). Por otro lado lo que se deshaga , tarde o temprano habrá que hacerlo, con lo cual el tiempo del batch puede llegar a triplicarse en determinados casos.
El uso de puntos de sincronismo implica:
 El programa deberá disponer de sentencias de rearranque desde el último Commit enviado para casos de terminaciones anormales
 Cuando se emite un Commit, se cierran todos los cursores abiertos en ese momento, excepto los declarados WITH HOLD, por lo que deben abrirse de nuevo después del commit. Para esto es necesario tener previsto el reposicionamiento de cursores.
 Hay que tener cuidado especial en el tratamiento de ficheros secuenciales.
Paralelismo
Se puede considerar la ejecución batch en paralelo desde dos puntos de vista.
 Procesos que realizan diferentes tareas
 El mismo proceso contra distintos datos
Para casos de paralelismo tipo ‘2’, existe la posibilidad de particionar tablas DB2, pudiendo un mismo proceso ejecutarse en paralelo cada uno contra una partición diferente:
El uso de paralelismo en Batch tiene los siguientes inconvenientes:
 Contenciones en CPU
 Contenciones en dispositivos de E/S
 Contenciones en datos DB2 debido a la estrategia de bloqueo
Por lo tanto cuando se decide el uso de ejecución en paralelo hay que asegurarse que no se van a producir cuellos de botella en el sistema.
Para evitar dichos cuellos de botella hay que tener en cuenta:
 Diseño de Tablas: Considerar el particionar tablas grandes, bien en espacios para tablas particionados, bien en dos tablas idénticas.
 Consideraciones de Bloqueo: Es primordial estudiar el orden en el que se adquieren los recursos por los programas que se ejecutan en paralelo.
 Contención por E/S:
o Distribución de datos en diferentes volúmenes.
o Separar en diferentes dispositivos datos de índices
o Ordenar el fichero de entrada según secuencia cluster
o Separar los ficheros de entrada en diferentes dispositivos


Casos Típicos

Extracción de múltiples informes en diferente secuencia
Para ello seguir los siguientes pasos:
 Descargar una única vez la tabla DB2 mediante UNLOAD
 Ordenar el fichero tantas veces como diferentes secuencias se necesiten
 Construir el informe a partir del fichero ordenado según necesidad

Procesos secuenciales de la misma tabla sin actualización
Utilizar la misma técnica que en el caso anterior

Actualización Masiva
1. Borrado Masivo
Opción 1:
 Descarga de los datos de la tabla
 Eliminación de los registros no deseados
 Load de los datos a la tabla con opción Replace
Opción 2:
 Descarga con opción Where de los datos que se desean mantener
 Load de los datos a la tabla con opción Replace
Estas opciones son válidas cuando el número de registros a borrar es importante con respecto al volumen total de la tabla.

Insert Masivo y Aleatorio
Opción 1:
 Descarga
 Sort entre datos descargados y datos nuevos en secuencia clúster
 Load con opción Replace

Insert Masivo y al Final
Opción 1:
 Sort de los datos nuevos en secuencia clúster
 Load con opción Resume
4. Modificación Masiva
Opción 1:
 Descarga de la tabla mediante Unload
 Actualización de los datos sobre ficheros
 Load con opción Replace
Ventajas e Inconvenientes:
 Ventajoso si la tabla necesita frecuentes reorganizaciones, ya que se evitaría hacerlas
 Reduce coste de mantenimiento de los índices No Clúster
 La tabla NO estará disponible mientras se ejecuta el proceso
Opción 2:
 Ordenar fichero de entrada según orden clúster
 Leer de la tabla
 Actualización de los datos como cruce de ficheros
Ventajas e Inconvenientes:
 Utiliza sequential prefetch
 Reduce el coste de CPU
 Eficiente para actualizaciones sobre más del 20% de los registros de la tabla
 Complica el proceso de rearranque y reposicionamiento


Opción 3:
 Ordenar fichero de entrada según orden clúster
 Leer fichero de entrada de forma secuencial
 Actualización de los datos de forma aleatoria, por clave
Ventajas e Inconvenientes:
 No utiliza sequential prefetch
 Alto coste de CPU por fila actualizada, si se pretende actualizar un 20% del total de registros de la tabla
 Es la alternativa más fácil de implementar

Join de Múltiples Tablas

Opción 1: Join DB2
Las decisiones de navegación las decide el DB2
Posibles problemas de Outer Join
Dificultad en la construcción de la sentencia SQL
Puede llegar a ser extremadamente costoso en tablas grandes

Opción 2: Navegación por Aplicación
La aplicación decide el mejor camino
 Problemas de coste sí las tablas no están ordenadas por los mismos campos (clúster)

Opción 3: Procesos individuales
 Seleccionar en Tabla-1
 Ordenar fichero resultante en orden al clúster de la Tabla-2
 Selección de datos de Tabla-2 según fichero de entrada ordenado

Esta opción sirve cuando los datos de la Tabla-1 nos sirven para seleccionar los datos de la Tabla-2

Opción 4: Extracción en paralelo y sort
 Realizar la selección de la Tabla-1 y de la Tabla-2 mediante procesos en paralelo
 Realizar un Sort-Merge con los datos de salida de ambos procesos
 Ejecutar proceso contra datos resultado

Opción 5: Algunas de las tablas es de parámetros, muy pequeña con relación a la otra.
 Cargar siempre la tabla pequeña en memoria working y acceder mediante sentencia Search.
avatar
Coboler@
Admin

Mensajes : 215
Reputación : 19
Fecha de inscripción : 02/02/2011
Edad : 37
Localización : Madrid

Ver perfil de usuario http://www.coboleros.es

Volver arriba Ir abajo

Ver el tema anterior Ver el tema siguiente Volver arriba


 
Permisos de este foro:
No puedes responder a temas en este foro.