Desarrollando en Cobol y Natural sobre Plataforma Mainframe
viernes, 25 de marzo de 2016
lunes, 21 de marzo de 2016
Query SQL con UNION y con UNION ALL (1)
En muchas ocasiones, tras implementar un determinado código SQL, nos damos cuenta de que su rendimiento a la hora de ejecutarse es bastante deficiente. Una forma de optimizar los tiempos de ejecución es recurrir a la cláusula UNION e incorporarla a nuestras queries siempre que sea posible. En este sentido, disponemos de dos variantes principales para codificar este comando: UNION ALL y UNION.
La instrucción UNION nos va a permitir integrar las extracciones realizadas por dos queries distintas. Si prescindimos de la cláusula UNION, lo más normal es que, en vez de unir dos queries sencillas, tengamos que recurrir a una query única de complejidad mucho mayor. Y, lo que es peor, el rendimiento de esta query compleja probablemente será muy inferior a la solución con UNION.
Por lo general (lo he podido comprobar en mi propia experiencia), una declaración SQL mediante UNION suele tener tiempos de ejecución mucho mejores que la misma extracción pero realizada mediante una query única más compleja (que integre la funcionalidad de las queries sencillas empleadas en dicho UNION). Esto lo he verificado con el uso del comando EXPLAIN, así que no merece la pena complicarse la vida.
Para ver cómo funcionaría la instrucción UNION vamos a ver un ejemplo en el que inicialmente no se ha empleado esta instrucción para mejorar el rendimiento del código.
SELECT *
FROM JJDB22.JJETRAT0 A, JJDB22.JJTRAMT0 B
WHERE
((A.JJTU_CO_INTERN = 'Z.BR' AND A.JJCA_CO_INTERN = 1)
OR (A.JJTU_CO_INTERN_1 = 'Z.BR' AND A.JJCA_CO_INTERN_1 = 1))
AND A.JJTU_CO_INTERN = B.JJTU_CO_INTERN
AND A.JJCA_CO_INTERN = B.JJCA_CO_INTERN
AND A.JJTU_CO_INTERN_1 = B.JJTU_CO_INTERN_1
AND A.JJCA_CO_INTERN_1 = B.JJCA_CO_INTERN_1
AND A.JJAM_NU_INTERN = B.JJAM_NU_INTERN
Aparentemente, esta query tiene un aspecto muy compacto y parece bien codificada pero, por desgracia, sus tiempos de ejecución eran superiores a 100 milisegundos. Por tanto, no hubo más remedio que pensar en formas de mejorar su rendimiento. Y aquí es donde entra en juego la cláusula UNION.
Una vez vista la query compleja, vamos a examinar cómo se podría mejorar el rendimiento de la misma mediante UNION. Para ello, lo que tendríamos que determinar es cómo se podría dividir la query inicial en varias subqueries más sencillas, de manera que posteriormente podamos unir estas subextracciones mediante la cláusula UNION.
En el ejemplo que nos ocupa, vemos que se está usando el operador OR en la cláusula WHERE. Por tanto, aquí lo más fácil sería dividir la query total en dos queries más pequeñas, de manera que cada una de ellas extraiga el contenido de cada operando del OR. Obviamente, estas subqueries tendrán tiempos de ejecución muy bajos, ya que su código será mucho más sencillo.
Dicho y hecho. Haciendo la división, estas serían las dos declaraciones que nos quedarían para las nuevas queries. La primera parte del OR sería la siguiente.
SELECT *
FROM JJDB22.JJETRAT0 A, JJDB22.JJTRAMT0 B
WHERE
( A.JJTU_CO_INTERN = 'Z.BR' AND A.JJCA_CO_INTERN = 1)
AND A.JJTU_CO_INTERN = B.JJTU_CO_INTERN
AND A.JJCA_CO_INTERN = B.JJCA_CO_INTERN
AND A.JJAM_NU_INTERN = B.JJAM_NU_INTERN
Y la segunda parte del OR sería esta.
SELECT *
FROM JJDB22.JJETRAT0 A, JJDB22.JJTRAMT0 B
WHERE
(A.JJTU_CO_INTERN_1 = 'Z.BR' AND A.JJCA_CO_INTERN_1 = 1)
AND A.JJTU_CO_INTERN_1 = B.JJTU_CO_INTERN_1
AND A.JJCA_CO_INTERN_1 = B.JJCA_CO_INTERN_1
AND A.JJAM_NU_INTERN = B.JJAM_NU_INTERN
Y ahora viene la parte que verdaderamente nos interesa. Una vez que hemos dividido la query padre en queries hijas más pequeñas, llega el momento de dar entrada a UNION. ¿Y cómo se utiliza esta cláusula en una query? Pues muy sencillo, simplemente hay que insertar la instrucción UNION entre las dos queries hijas del siguiente modo.
SELECT *
FROM JJDB22.JJETRAT0 A, JJDB22.JJTRAMT0 B
WHERE
( A.JJTU_CO_INTERN = 'Z.BR' AND A.JJCA_CO_INTERN = 1)
AND A.JJTU_CO_INTERN = B.JJTU_CO_INTERN
AND A.JJCA_CO_INTERN = B.JJCA_CO_INTERN
AND A.JJAM_NU_INTERN = B.JJAM_NU_INTERN
UNION
SELECT *
FROM JJDB22.JJETRAT0 A, JJDB22.JJTRAMT0 B
WHERE
(A.JJTU_CO_INTERN_1 = 'Z.BR' AND A.JJCA_CO_INTERN_1 = 1)
AND A.JJTU_CO_INTERN_1 = B.JJTU_CO_INTERN_1
AND A.JJCA_CO_INTERN_1 = B.JJCA_CO_INTERN_1
AND A.JJAM_NU_INTERN = B.JJAM_NU_INTERN
El listado extraído por el UNION anterior es idéntico al que hubiésemos obtenido mediante la ejecución de la query inicial más compleja. La única diferencia es que, mediante el uso del UNION, hemos conseguido que su tiempo de ejecución caiga por debajo de los 100 milisegundos y, por tanto, que ya tengamos entre nuestras manos un código adecuado para entregar al cliente.
-------------------------------------------------------------------------------------------------------------------------------
Tip: Aquí te explico cómo almacenar queries en QMF y también cómo recuperar queries en QMF.
-------------------------------------------------------------------------------------------------------------------------------
Hasta aquí todo lo que teníamos que ver sobre la implementación de una query con UNION. El próximo día, en un nuevo post, trataremos de revisar el funcionamiento de la cláusula UNION ALL en una sentencia SQL. Hay ciertas diferencias entre ambas instrucciones y es importante que las tengamos en cuenta a la hora de desarrollar los accesos a DB2 en nuestros programas Cobol.
Pues nada, eso es todo por hoy. Como siempre, quedáis citados a la segunda parte del post, donde completaremos la visión global de UNION y de UNION ALL. Espero (y deseo) que lo comentado os sea de la máxima utilidad...
Saludos.
Rendimiento de Query SQL con UNION
La instrucción UNION nos va a permitir integrar las extracciones realizadas por dos queries distintas. Si prescindimos de la cláusula UNION, lo más normal es que, en vez de unir dos queries sencillas, tengamos que recurrir a una query única de complejidad mucho mayor. Y, lo que es peor, el rendimiento de esta query compleja probablemente será muy inferior a la solución con UNION.
Por lo general (lo he podido comprobar en mi propia experiencia), una declaración SQL mediante UNION suele tener tiempos de ejecución mucho mejores que la misma extracción pero realizada mediante una query única más compleja (que integre la funcionalidad de las queries sencillas empleadas en dicho UNION). Esto lo he verificado con el uso del comando EXPLAIN, así que no merece la pena complicarse la vida.
Para ver cómo funcionaría la instrucción UNION vamos a ver un ejemplo en el que inicialmente no se ha empleado esta instrucción para mejorar el rendimiento del código.
SELECT *
FROM JJDB22.JJETRAT0 A, JJDB22.JJTRAMT0 B
WHERE
((A.JJTU_CO_INTERN = 'Z.BR' AND A.JJCA_CO_INTERN = 1)
OR (A.JJTU_CO_INTERN_1 = 'Z.BR' AND A.JJCA_CO_INTERN_1 = 1))
AND A.JJTU_CO_INTERN = B.JJTU_CO_INTERN
AND A.JJCA_CO_INTERN = B.JJCA_CO_INTERN
AND A.JJTU_CO_INTERN_1 = B.JJTU_CO_INTERN_1
AND A.JJCA_CO_INTERN_1 = B.JJCA_CO_INTERN_1
AND A.JJAM_NU_INTERN = B.JJAM_NU_INTERN
Aparentemente, esta query tiene un aspecto muy compacto y parece bien codificada pero, por desgracia, sus tiempos de ejecución eran superiores a 100 milisegundos. Por tanto, no hubo más remedio que pensar en formas de mejorar su rendimiento. Y aquí es donde entra en juego la cláusula UNION.
¿Cómo codificar una Query SQL con UNION?
Una vez vista la query compleja, vamos a examinar cómo se podría mejorar el rendimiento de la misma mediante UNION. Para ello, lo que tendríamos que determinar es cómo se podría dividir la query inicial en varias subqueries más sencillas, de manera que posteriormente podamos unir estas subextracciones mediante la cláusula UNION.
En el ejemplo que nos ocupa, vemos que se está usando el operador OR en la cláusula WHERE. Por tanto, aquí lo más fácil sería dividir la query total en dos queries más pequeñas, de manera que cada una de ellas extraiga el contenido de cada operando del OR. Obviamente, estas subqueries tendrán tiempos de ejecución muy bajos, ya que su código será mucho más sencillo.
Dicho y hecho. Haciendo la división, estas serían las dos declaraciones que nos quedarían para las nuevas queries. La primera parte del OR sería la siguiente.
SELECT *
FROM JJDB22.JJETRAT0 A, JJDB22.JJTRAMT0 B
WHERE
( A.JJTU_CO_INTERN = 'Z.BR' AND A.JJCA_CO_INTERN = 1)
AND A.JJTU_CO_INTERN = B.JJTU_CO_INTERN
AND A.JJCA_CO_INTERN = B.JJCA_CO_INTERN
AND A.JJAM_NU_INTERN = B.JJAM_NU_INTERN
Y la segunda parte del OR sería esta.
SELECT *
FROM JJDB22.JJETRAT0 A, JJDB22.JJTRAMT0 B
WHERE
(A.JJTU_CO_INTERN_1 = 'Z.BR' AND A.JJCA_CO_INTERN_1 = 1)
AND A.JJTU_CO_INTERN_1 = B.JJTU_CO_INTERN_1
AND A.JJCA_CO_INTERN_1 = B.JJCA_CO_INTERN_1
AND A.JJAM_NU_INTERN = B.JJAM_NU_INTERN
Y ahora viene la parte que verdaderamente nos interesa. Una vez que hemos dividido la query padre en queries hijas más pequeñas, llega el momento de dar entrada a UNION. ¿Y cómo se utiliza esta cláusula en una query? Pues muy sencillo, simplemente hay que insertar la instrucción UNION entre las dos queries hijas del siguiente modo.
SELECT *
FROM JJDB22.JJETRAT0 A, JJDB22.JJTRAMT0 B
WHERE
( A.JJTU_CO_INTERN = 'Z.BR' AND A.JJCA_CO_INTERN = 1)
AND A.JJTU_CO_INTERN = B.JJTU_CO_INTERN
AND A.JJCA_CO_INTERN = B.JJCA_CO_INTERN
AND A.JJAM_NU_INTERN = B.JJAM_NU_INTERN
UNION
SELECT *
FROM JJDB22.JJETRAT0 A, JJDB22.JJTRAMT0 B
WHERE
(A.JJTU_CO_INTERN_1 = 'Z.BR' AND A.JJCA_CO_INTERN_1 = 1)
AND A.JJTU_CO_INTERN_1 = B.JJTU_CO_INTERN_1
AND A.JJCA_CO_INTERN_1 = B.JJCA_CO_INTERN_1
AND A.JJAM_NU_INTERN = B.JJAM_NU_INTERN
El listado extraído por el UNION anterior es idéntico al que hubiésemos obtenido mediante la ejecución de la query inicial más compleja. La única diferencia es que, mediante el uso del UNION, hemos conseguido que su tiempo de ejecución caiga por debajo de los 100 milisegundos y, por tanto, que ya tengamos entre nuestras manos un código adecuado para entregar al cliente.
-------------------------------------------------------------------------------------------------------------------------------
Tip: Aquí te explico cómo almacenar queries en QMF y también cómo recuperar queries en QMF.
-------------------------------------------------------------------------------------------------------------------------------
Hasta aquí todo lo que teníamos que ver sobre la implementación de una query con UNION. El próximo día, en un nuevo post, trataremos de revisar el funcionamiento de la cláusula UNION ALL en una sentencia SQL. Hay ciertas diferencias entre ambas instrucciones y es importante que las tengamos en cuenta a la hora de desarrollar los accesos a DB2 en nuestros programas Cobol.
Pues nada, eso es todo por hoy. Como siempre, quedáis citados a la segunda parte del post, donde completaremos la visión global de UNION y de UNION ALL. Espero (y deseo) que lo comentado os sea de la máxima utilidad...
Saludos.
lunes, 14 de marzo de 2016
Transacción CMAC: Mensajes de error CICS
La transacción CMAC de CICS es una herramienta muy sencilla, pero que nos va a permitir acceder a una explicación detallada del error CICS que nos esté bloqueando el avance en un momento dado. Aunque su uso no supone complejidad alguna, a mi siempre me gusta incluirla en la lista de transacciones básicas CICS, fundamentalmente debido a su gran utilidad. Estoy seguro de que a vosotros también os gustará disponer de esta ayuda en vuestra instalación.
En líneas generales, podemos decir que la transacción CMAC nos permite introducir un determinado código de error y, a partir de él, nos va a devolver una explicación del mensaje de error. También nos proporcionará algunas directrices de cómo podríamos proceder para tratar de subsanar el problema con el que nos hemos encontrado. Se trata, por tanto, de una base de datos de errores CICS.
A continuación, vamos a enumerar los pasos necesarios para poder recuperar la información mencionada. Son los siguientes.
1º) En primer lugar, procedemos a entrar en la sesión CICS y, una vez dentro, introducimos la transacción CMAC.
2º) Tras pulsar INTRO, se nos desplegará la ventana inicial de la herramienta, en donde aparecen dos campos pendientes de provisionar: COMPONENT ID y MESSAGE NUMBER.
En el campo COMPONENT ID tendremos que indicar la tipología del error y en MESSAGE NUMBER habrá que especificar el código numérico del mensaje de error o aviso para el que queremos conocer más detalles. Por ejemplo, en la imagen anterior hemos introducido "TC" y "1060" (correspondientes al error CICS DFHTC1060).
3º) Si insertamos COMPONENT ID y MESSAGE NUMBER y, a continuación, pulsamos INTRO, la aplicación nos llevará a la ventana de detalle del mensaje.
En el ejemplo podemos ver que en dicha ventana se muestra el título DFHTC1060 APPLID INSUFFICIENT STORAGE - CODE(X'CODE') IN MODULE DFHTCRP. En el informe nos aparecen varios apartados (EXPLANATION, SYSTEM ACTION, USER RESPONSE, DESTINATION, MODULE y MESSAGE INSERTS) en los que se nos va explicando detalladamente en qué consiste el error y cuáles son las medidas que podemos tomar para tratar de subsanarlo.
Y no hay mucho más que comentar acerca de esta transacción. Se trata de una herramienta de uso sencillo y con un objetivo muy definido. Eso sí, las explicaciones de los errores son detalladas y útiles. En más de una ocasión os puede dar buenas ideas acerca de cómo superar ese error CICS que os está impidiendo avanzar tanto con el desarrollo de vuestros módulos Cobol como con la implementación de las fases JCL.
Eso sí, verificad que en vuestra instalación está disponible. He comprobado que algunas empresas se olvidan de instalar CMAC y, entonces, no podréis acceder a esta ayuda en vuestro día a día. Si tenéis la posibilidad, pedidle a vuestro cliente que lo instale en el entorno.
Como he dicho al principio, aunque en muchos listados no aparezca, yo siempre incluyo a CMAC entre las transacciones básicas de CICS. Ya sé que es una transacción muy sencilla, pero el hecho de que una herramienta sea simple no significa que no sea importante para nuestro desempeño. Ya lo iréis comprobando con el tiempo.
Y eso es todo por lo que respecta a CMAC. Supongo que os habrá quedado bastante claro el funcionamiento de la transacción pero, si no es así, no dudéis en dejarme los comentarios que creáis convenientes...
Saludos.
Transacción CMAC: Mensajes de error
En líneas generales, podemos decir que la transacción CMAC nos permite introducir un determinado código de error y, a partir de él, nos va a devolver una explicación del mensaje de error. También nos proporcionará algunas directrices de cómo podríamos proceder para tratar de subsanar el problema con el que nos hemos encontrado. Se trata, por tanto, de una base de datos de errores CICS.
A continuación, vamos a enumerar los pasos necesarios para poder recuperar la información mencionada. Son los siguientes.
1º) En primer lugar, procedemos a entrar en la sesión CICS y, una vez dentro, introducimos la transacción CMAC.
2º) Tras pulsar INTRO, se nos desplegará la ventana inicial de la herramienta, en donde aparecen dos campos pendientes de provisionar: COMPONENT ID y MESSAGE NUMBER.
En el campo COMPONENT ID tendremos que indicar la tipología del error y en MESSAGE NUMBER habrá que especificar el código numérico del mensaje de error o aviso para el que queremos conocer más detalles. Por ejemplo, en la imagen anterior hemos introducido "TC" y "1060" (correspondientes al error CICS DFHTC1060).
3º) Si insertamos COMPONENT ID y MESSAGE NUMBER y, a continuación, pulsamos INTRO, la aplicación nos llevará a la ventana de detalle del mensaje.
En el ejemplo podemos ver que en dicha ventana se muestra el título DFHTC1060 APPLID INSUFFICIENT STORAGE - CODE(X'CODE') IN MODULE DFHTCRP. En el informe nos aparecen varios apartados (EXPLANATION, SYSTEM ACTION, USER RESPONSE, DESTINATION, MODULE y MESSAGE INSERTS) en los que se nos va explicando detalladamente en qué consiste el error y cuáles son las medidas que podemos tomar para tratar de subsanarlo.
Conclusiones sobre la Transacción CMAC
Y no hay mucho más que comentar acerca de esta transacción. Se trata de una herramienta de uso sencillo y con un objetivo muy definido. Eso sí, las explicaciones de los errores son detalladas y útiles. En más de una ocasión os puede dar buenas ideas acerca de cómo superar ese error CICS que os está impidiendo avanzar tanto con el desarrollo de vuestros módulos Cobol como con la implementación de las fases JCL.
Eso sí, verificad que en vuestra instalación está disponible. He comprobado que algunas empresas se olvidan de instalar CMAC y, entonces, no podréis acceder a esta ayuda en vuestro día a día. Si tenéis la posibilidad, pedidle a vuestro cliente que lo instale en el entorno.
Como he dicho al principio, aunque en muchos listados no aparezca, yo siempre incluyo a CMAC entre las transacciones básicas de CICS. Ya sé que es una transacción muy sencilla, pero el hecho de que una herramienta sea simple no significa que no sea importante para nuestro desempeño. Ya lo iréis comprobando con el tiempo.
Y eso es todo por lo que respecta a CMAC. Supongo que os habrá quedado bastante claro el funcionamiento de la transacción pero, si no es así, no dudéis en dejarme los comentarios que creáis convenientes...
Saludos.
lunes, 7 de marzo de 2016
EXPLAIN con CA SQL-Ease for DB2 for ZOS (y 2)
Hace algunas semanas estuvimos viendo cómo se podía lanzar un chequeo EXPLAIN sobre una sentencia SQL de un programa Cobol. Esta función nos permitía obtener un informe (ACCESS PATH ANALYSIS) en el que se nos mostraba información acerca de las tablas DB2 utilizadas en nuestro objeto. Lo más importante es que se nos indicaba el coste, en milisegundos, que iba a requerir la ejecución de las instrucciones SQL.
En la primera parte del presente artículo estuvimos viendo cómo lanzar un EXPLAIN desde el editor de nuestro programa Cobol (ver post EXPLAIN con CA SQL-Ease for DB2 for ZOS - 1). Hoy veremos cómo se podría lanzar este mismo chequeo EXPLAIN desde el informe ACCESS PATH ANALYSIS. De esta forma, ahorraremos tiempo a la hora de analizar el rendimiento de nuestro programa, ya que no tendremos que estar cambiando entre el editor del objeto y la herramienta CA SQL-Ease for DB2 for ZOS.
Con lo examinado en el anterior post ya podemos dar por vistos los pasos que tenemos que seguir para ejecutar un EXPLAIN en la herramienta CA SQL-Ease for DB2 for ZOS. Ahora os comentaré otra funcionalidad interesante que podemos encontrar en esta aplicación.
1º) Una vez estamos en el informe ACCESS PATH ANALYSIS, podemos irnos al final del todo escribiendo 'M' en la línea de comandos y pulsando PF8. Así nos aparecerá en pantalla el código de la query para la se ha ejecutado el informe EXPLAIN.
Lo bueno es que en esta misma pantalla podremos proceder a modificar la query como deseemos. Esto nos permitirá probar diversas alternativas para optimizar el código y nos facilitará la realización del trabajo necesario para rebajar el coste por debajo de los 100 milisegundos.
2º) Una vez que hayamos terminado las modificaciones necesarias, podremos obtener de nuevo fácilmente el informe ACCESS PATH ANALYSIS para la query optimizada. Para ello, simplemente tendremos que introducir la instrucción EXPLAIN en la línea de comandos.
Tras pulsar INTRO se nos volverá a mostrar el informe EXPLAIN pero esta vez con los datos de Coste actualizados según las nuevas modificaciones que hayamos introducido en la query. Y lo mejor de todo es que podremos repetir este proceso tantas veces como necesitemos hasta que estemos totalmente seguros de que nuestro código no va a superar los 100 milisegundos de ejecución.
Hay ocasiones en las que implementamos un determinado código SQL y, cuando realizamos las pruebas en ejecución, nos damos cuenta de que el rendimiento del nuevo programa es muy inferior al esperado. Y lo peor es que, en muchos casos, es complicado determinar cuál es la query que está provocando el cuello de botella en la aplicación, sobre todo cuando trabajamos con código que contiene subqueries anidadas.
Para estos casos nos va a venir muy el empleo de la herramienta CA SQL-Ease for DB2 for ZOS. En particular, la opción 2 de la misma (EXPLAIN SQL) nos resultará muy útil para evaluar el rendimiento de las implementaciones SQL. Y, por supuesto, esto repercutirá en el rendimiento global de nuestros programas Cobol.
El lanzamiento del EXPLAIN nos proporcionará un informe ACCESS PATH ANALYSIS correspondiente a la query que hayamos seleccionado. Entre los resultados de dicho informe nos encontraremos el de Coste (en milisegundos), dato que nos resultará muy útil a la hora de verificar que nuestro código tiene un rendimiento aceptable.
Llegados a este punto, ahora ya es decisión vuestra incorporar esta función a vuestro catálogo de herramientas Cobol. Por mi parte, yo hace tiempo que la uso y nunca entregaría un programa al cliente sin comprobar que sus accesos SQL son óptimos. Creedme cuando os digo que esto, a largo plazo, será beneficioso para vosotros.
Pues nada, eso es todo lo que quería comentaros con respecto a CA SQL-Ease for DB2 for ZOS. Si tenéis la suerte de disponer de esta aplicación en vuestra instalación, no dudéis en utilizarla. Cualquier duda, ya sabéis que podéis dejarla aquí debajo.
Saludos.
En la primera parte del presente artículo estuvimos viendo cómo lanzar un EXPLAIN desde el editor de nuestro programa Cobol (ver post EXPLAIN con CA SQL-Ease for DB2 for ZOS - 1). Hoy veremos cómo se podría lanzar este mismo chequeo EXPLAIN desde el informe ACCESS PATH ANALYSIS. De esta forma, ahorraremos tiempo a la hora de analizar el rendimiento de nuestro programa, ya que no tendremos que estar cambiando entre el editor del objeto y la herramienta CA SQL-Ease for DB2 for ZOS.
Lanzar EXPLAIN desde ACCESS PATH ANALYSIS
Con lo examinado en el anterior post ya podemos dar por vistos los pasos que tenemos que seguir para ejecutar un EXPLAIN en la herramienta CA SQL-Ease for DB2 for ZOS. Ahora os comentaré otra funcionalidad interesante que podemos encontrar en esta aplicación.
1º) Una vez estamos en el informe ACCESS PATH ANALYSIS, podemos irnos al final del todo escribiendo 'M' en la línea de comandos y pulsando PF8. Así nos aparecerá en pantalla el código de la query para la se ha ejecutado el informe EXPLAIN.
Lo bueno es que en esta misma pantalla podremos proceder a modificar la query como deseemos. Esto nos permitirá probar diversas alternativas para optimizar el código y nos facilitará la realización del trabajo necesario para rebajar el coste por debajo de los 100 milisegundos.
2º) Una vez que hayamos terminado las modificaciones necesarias, podremos obtener de nuevo fácilmente el informe ACCESS PATH ANALYSIS para la query optimizada. Para ello, simplemente tendremos que introducir la instrucción EXPLAIN en la línea de comandos.
Tras pulsar INTRO se nos volverá a mostrar el informe EXPLAIN pero esta vez con los datos de Coste actualizados según las nuevas modificaciones que hayamos introducido en la query. Y lo mejor de todo es que podremos repetir este proceso tantas veces como necesitemos hasta que estemos totalmente seguros de que nuestro código no va a superar los 100 milisegundos de ejecución.
Conclusiones acerca de CA SQL-Ease for DB2 for ZOS
Hay ocasiones en las que implementamos un determinado código SQL y, cuando realizamos las pruebas en ejecución, nos damos cuenta de que el rendimiento del nuevo programa es muy inferior al esperado. Y lo peor es que, en muchos casos, es complicado determinar cuál es la query que está provocando el cuello de botella en la aplicación, sobre todo cuando trabajamos con código que contiene subqueries anidadas.
Para estos casos nos va a venir muy el empleo de la herramienta CA SQL-Ease for DB2 for ZOS. En particular, la opción 2 de la misma (EXPLAIN SQL) nos resultará muy útil para evaluar el rendimiento de las implementaciones SQL. Y, por supuesto, esto repercutirá en el rendimiento global de nuestros programas Cobol.
El lanzamiento del EXPLAIN nos proporcionará un informe ACCESS PATH ANALYSIS correspondiente a la query que hayamos seleccionado. Entre los resultados de dicho informe nos encontraremos el de Coste (en milisegundos), dato que nos resultará muy útil a la hora de verificar que nuestro código tiene un rendimiento aceptable.
Llegados a este punto, ahora ya es decisión vuestra incorporar esta función a vuestro catálogo de herramientas Cobol. Por mi parte, yo hace tiempo que la uso y nunca entregaría un programa al cliente sin comprobar que sus accesos SQL son óptimos. Creedme cuando os digo que esto, a largo plazo, será beneficioso para vosotros.
Pues nada, eso es todo lo que quería comentaros con respecto a CA SQL-Ease for DB2 for ZOS. Si tenéis la suerte de disponer de esta aplicación en vuestra instalación, no dudéis en utilizarla. Cualquier duda, ya sabéis que podéis dejarla aquí debajo.
Saludos.
lunes, 29 de febrero de 2016
EXPLAIN con CA SQL-Ease for DB2 for ZOS (1)
En ocasiones, al ejecutar nuestros programas Cobol nos damos cuenta de que el rendimiento está siendo muy inferior al que estábamos esperando en el momento de su codificación. En estos casos, lo difícil es determinar el punto exacto del código donde se está produciendo el cuello de botella. El comando EXPLAIN de la herramienta CA SQL-Ease for DB2 for ZOS nos va a permitir medir la velocidad de ejecución de cada una de las sentencias SQL que hayamos incluido en nuestro programa.
Supongo que, al igual que a mi, en ocasiones os habrá ocurrido que, tras terminar la codificación de un Cobol, procedéis a ejecutarlo y descubrís que su rendimiento en máquina está siendo bastante deficiente. En estos casos, ¿cómo podemos determinar el punto del programa que está provocando el retraso de la ejecución? Para ayudarnos a realizar esta búsqueda disponemos de la herramienta CA SQL-Ease for DB2 for ZOS.
El comando EXPLAIN de CA SQL-Ease for DB2 for ZOS nos sirve para medir el tiempo estimado de ejecución de una sentencia SQL. Recordad que no deberíamos poner en producción ninguna sentencia cuyo tiempo de ejecución sea superior a los 100 milisegundos. Teniendo en cuenta esto, EXPLAIN nos va a permitir detectar cuáles son las instrucciones SQL de nuestro programa que van a tener un pobre rendimiento a la hora de ejecutarse.
Hay que tener en cuenta que se trata de una aplicación muy potente. Su uso nos va a permitir que las sentencias SQL de nuestros programas Cobol lleguen al entorno de producción con tiempos de ejecución inferiores a 100 ms. Obviamente, siempre es posible que surja algún error adicional pero no podemos negar que, con EXPLAIN, las posibilidades de que se produzca un problema de rendimiento son muy inferiores.
Entrando ya en materia, ahora vamos a ir viendo cuáles son los pasos que tendríamos que seguir para ejecutar el comando EXPLAIN en nuestro programa Cobol. Como veréis, no se trata de algo complicado. Una vez que hayamos realizado el procedimiento por primera vez, el resto de las ejecuciones las podremos realizar casi sin esfuerzo.
Estos son los pasos:
1º) En primer lugar, tendremos que proceder a seleccionar el programa a valorar y entrar en el código del objeto en modo edición.
2º) Nos situamos en la declaración SQL para la que deseamos obtener una evaluación de su rendimiento en ejecución. Os recuerdo que este tipo de declaraciones estarán situadas entre cualquiera de las instrucciones EXEC SQL y END-EXEC de nuestro programa.
3º) A continuación, insertamos una E en alguna de las líneas de la declaración SQL. Esta marca debe introducirse en la columna en la que figura el número de línea del programa.
4º) Introducimos la instrucción SQLEASE en la línea de comandos. Esto hará que se arranque la aplicación CA SQL-Ease for DB2 for ZOS.
5º) Tras pulsar INTRO se nos abrirá el menú principal de la herramienta. Aquí tendremos que seleccionar la opción 2 - EXPLAIN SQL.
6º) A continuación, se nos mostrará un informe en el que podremos ver toda la información asociada a la evaluación del rendimiento de ejecución de la sentencia SQL seleccionada.
7º) Si nos desplazamos una página hacia abajo, podremos ver la información del rendimiento de la ejecución en el apartado ACCESS PATH ANALYSIS. En la línea COST encontraremos el importante dato que hace referencia al tiempo (en milisegundos) que tardará en ejecutarse nuestra sentencia SQL.
En el ejemplo vemos que el coste del SQL sería de 284 milisegundos. Como hemos dicho más arriba, cualquier cosa que pase de los 100 milisegundos no es aceptable y, por tanto, tendríamos que proceder a la optimización de nuestro código antes de entregarlo al cliente.
8º) Adicionalmente, en el análisis del camino de acceso también podremos encontrar información acerca de las tablas a las que se va entrando y el índice por el que se está accediendo a las mismas en la query SQL analizada.
En el ejemplo vemos que se está accediendo a la tabla DB2 denominada SITUTD mediante el índice SITUI2. Este camino de acceso nos puede ayudar y darnos ideas a la hora de optimizar la query analizada (en el caso de que sea necesario proceder a su modificación).
Si seguimos los pasos anteriormente comentados no tendremos problemas para ejecutar un EXPLAIN desde el editor de nuestro programa Cobol. El próximo día, en un nuevo post, os explicaré cómo podemos lanzar un chequeo EXPLAIN desde el propio informe ACCESS PATH ANALYSIS. Esta segunda funcionalidad nos vendrá muy bien para ir haciendo pruebas a la hora de reducir el consumo de una sentencia SQL por debajo de los 100 milisegundos.
Pues nada, eso es todo por ahora. Quedáis invitados a la segunda parte del post, donde completaremos nuestra visión inicial (básica) de la herramienta CA SQL-Ease for DB2 for ZOS. Espero volver a veros por aquí...
Saludos.
EXPLAIN con CA SQL-Ease for DB2 for ZOS
Supongo que, al igual que a mi, en ocasiones os habrá ocurrido que, tras terminar la codificación de un Cobol, procedéis a ejecutarlo y descubrís que su rendimiento en máquina está siendo bastante deficiente. En estos casos, ¿cómo podemos determinar el punto del programa que está provocando el retraso de la ejecución? Para ayudarnos a realizar esta búsqueda disponemos de la herramienta CA SQL-Ease for DB2 for ZOS.
El comando EXPLAIN de CA SQL-Ease for DB2 for ZOS nos sirve para medir el tiempo estimado de ejecución de una sentencia SQL. Recordad que no deberíamos poner en producción ninguna sentencia cuyo tiempo de ejecución sea superior a los 100 milisegundos. Teniendo en cuenta esto, EXPLAIN nos va a permitir detectar cuáles son las instrucciones SQL de nuestro programa que van a tener un pobre rendimiento a la hora de ejecutarse.
Hay que tener en cuenta que se trata de una aplicación muy potente. Su uso nos va a permitir que las sentencias SQL de nuestros programas Cobol lleguen al entorno de producción con tiempos de ejecución inferiores a 100 ms. Obviamente, siempre es posible que surja algún error adicional pero no podemos negar que, con EXPLAIN, las posibilidades de que se produzca un problema de rendimiento son muy inferiores.
¿Cómo ejecutar EXPLAIN en un Cobol?
Entrando ya en materia, ahora vamos a ir viendo cuáles son los pasos que tendríamos que seguir para ejecutar el comando EXPLAIN en nuestro programa Cobol. Como veréis, no se trata de algo complicado. Una vez que hayamos realizado el procedimiento por primera vez, el resto de las ejecuciones las podremos realizar casi sin esfuerzo.
Estos son los pasos:
1º) En primer lugar, tendremos que proceder a seleccionar el programa a valorar y entrar en el código del objeto en modo edición.
2º) Nos situamos en la declaración SQL para la que deseamos obtener una evaluación de su rendimiento en ejecución. Os recuerdo que este tipo de declaraciones estarán situadas entre cualquiera de las instrucciones EXEC SQL y END-EXEC de nuestro programa.
3º) A continuación, insertamos una E en alguna de las líneas de la declaración SQL. Esta marca debe introducirse en la columna en la que figura el número de línea del programa.
4º) Introducimos la instrucción SQLEASE en la línea de comandos. Esto hará que se arranque la aplicación CA SQL-Ease for DB2 for ZOS.
5º) Tras pulsar INTRO se nos abrirá el menú principal de la herramienta. Aquí tendremos que seleccionar la opción 2 - EXPLAIN SQL.
6º) A continuación, se nos mostrará un informe en el que podremos ver toda la información asociada a la evaluación del rendimiento de ejecución de la sentencia SQL seleccionada.
7º) Si nos desplazamos una página hacia abajo, podremos ver la información del rendimiento de la ejecución en el apartado ACCESS PATH ANALYSIS. En la línea COST encontraremos el importante dato que hace referencia al tiempo (en milisegundos) que tardará en ejecutarse nuestra sentencia SQL.
En el ejemplo vemos que el coste del SQL sería de 284 milisegundos. Como hemos dicho más arriba, cualquier cosa que pase de los 100 milisegundos no es aceptable y, por tanto, tendríamos que proceder a la optimización de nuestro código antes de entregarlo al cliente.
8º) Adicionalmente, en el análisis del camino de acceso también podremos encontrar información acerca de las tablas a las que se va entrando y el índice por el que se está accediendo a las mismas en la query SQL analizada.
En el ejemplo vemos que se está accediendo a la tabla DB2 denominada SITUTD mediante el índice SITUI2. Este camino de acceso nos puede ayudar y darnos ideas a la hora de optimizar la query analizada (en el caso de que sea necesario proceder a su modificación).
Si seguimos los pasos anteriormente comentados no tendremos problemas para ejecutar un EXPLAIN desde el editor de nuestro programa Cobol. El próximo día, en un nuevo post, os explicaré cómo podemos lanzar un chequeo EXPLAIN desde el propio informe ACCESS PATH ANALYSIS. Esta segunda funcionalidad nos vendrá muy bien para ir haciendo pruebas a la hora de reducir el consumo de una sentencia SQL por debajo de los 100 milisegundos.
Pues nada, eso es todo por ahora. Quedáis invitados a la segunda parte del post, donde completaremos nuestra visión inicial (básica) de la herramienta CA SQL-Ease for DB2 for ZOS. Espero volver a veros por aquí...
Saludos.
viernes, 1 de enero de 2016
Feliz Año Nuevo 2016
Ya sé que hoy estamos todos un poco cansados y con pocas ganas de
hacer nada, así que no voy a demorarme demasiado. Simplemente quería
daros un saludo rápido y desearos una feliz entrada de año nuevo. Espero
que en 2016 tengáis éxito en todos los objetivos que os marquéis en el mundo de la informática y, por qué no, en el resto de objetivos también
(por cierto, ¿os comísteis todas las uvas ayer?). Ahora, a descansar y a
disfrutar de la comida con vuestra familia. El lunes nos vemos de nuevo programando código al pie del cañón.
¡Feliz Año Nuevo 2016!
Saludos.
¡Feliz Año Nuevo 2016!
Saludos.
lunes, 9 de noviembre de 2015
¿Cómo recuperar queries en QMF?
Hace algunas semanas estuvimos viendo cómo se puede almacenar una query en la base de datos de QMF. Una vez que tenemos dicha información a salvo, hoy vamos a centrarnos en revisar cuáles son los comandos que tenemos disponibles para poder recuperar dichas querys de la base de datos.
En su día ya estuvimos viendo la instrucción SAVE de QMF, que nos permitía guardar cualquier tipo de código que tuviésemos escrito en el menú DRAW. Junto a ella, como veremos a continuación, tenemos otros otros dos comandos que nos van a venir muy bien a la hora de reutilizar nuestras queries de uso más frecuente. Se trata de DISPLAY QUERY y de LIST QUERIES.
Una vez almacenada la información, la siguiente cuestión que se nos plantearía es cómo recuperar la query en el momento en el que lo deseemos. Obviamente, no tendría mucho sentido almacenar el código si no pensamos usarlo nunca más con posterioridad.
En este entorno, para realizar la acción de recuperar la query en QMF disponemos del comando DISPLAY. Para poder usarlo, en primer lugar tendremos que posicionarnos en la ventana 6=DRAW de la herramienta QMF, tal y como hicimos a la hora de guardar el código.
Una vez aquí, en la línea COMMAND tendremos que incluir el comando DISPLAY QUERY.
COMMAND ===> DISPLAY QUERY EJEMPLO
Pulsamos INTRO y se nos deplegará la siguiente ventana.
Como se puede apreciar, se trata del mismo código que previamente habíamos almacenado con el comando SAVE. Una vez recuperada, esta declaración ya se podría ejecutar del mismo modo que se haría con cualquier otra query de QMF.
Imaginaos que llega un momento en el que tenéis almacenadas 50 queries en vuestro QMF y, por la razón que sea, un cliente os pide que obtengáis de nuevo un informe cuya query lanzásteis hace más de un año. Lo más probable es que no os acordéis del nombre con el que la guardásteis. Entonces, ¿cómo podríais acceder de nuevo a ella?
Para estos casos vamos a usar el comando LIST, que nos mostrará un listado de todas las queries que nuestro usuario tiene almacenadas en la base de datos de QMF. De nuevo, para poder usarlo, en primer lugar tendremos que posicionarnos en la ventana 6=DRAW de la herramienta QMF.
Una vez aquí, en la línea COMMAND tendremos que incluir el comando LIST QUERIES.
COMMAND ===> LIST QUERIES
Pulsamos INTRO y se nos deplegará la siguiente ventana.
Como vemos, en esta pantalla aparecen las queries que previamente he almacenado en QMF con mi usuario.
A continuación, si queremos recuperar el código de alguno de los objetos SQL listados, lo único que tendremos que hacer es usar el comando DISPLAY en la columna ACTION. De este modo, se recuperará el contenido de la query de la misma forma que con el comando DISPLAY QUERY que hemos examinado anteriormente.
--------Dates--------
Action Name Owner Modified Last Used
DISPLAY EJEMPLO JJ00917 2015-10-06 2015-10-07
Esta sería el método estándar para recuperar una query de nuestra base de datos de QMF siempre que no recordemos el nombre con el que la almacenamos en su día.
En principio, con los comandos revisados, ya podríamos operar de una manera básica con la base de datos de QMF. Las instrucciones SAVE, DISPLAY y LIST nos permitirán almacenar las queries que vayamos creando y recuperarlas siempre que tengamos necesidad de ellas (independientemente de que nos encontremos ante un tratamiento con la instrucción SELECT, con UPDATE, con INSERT o con DELETE).
Por supuesto, existen más comandos QMF que los aquí mencionados, pero con estas 3 instrucciones ya podremos sobrevivir en el entorno. En un futuro, en un nuevo post, intentaré esbozar una visión global de cuáles son todos los comandos disponibles para esta herramienta.
Aunque siempre habrá queries que sólo queramos usar una vez y que puedan ser desechadas tras su uso, lo importante es que tengamos la posibilidad de reutilizar fácilmente las queries que deban ser ejecutadas periódicamente. Esa función podrá ser realizada de forma eficiente con las instrucciones QMF revisadas hoy.
En principio, siguiendo los pasos aquí comentados no deberíais tener problemas a la hora de trabajar en el entorno. De todas formas, cualquier problema o duda que os surja, ya sabéis que podéis dejármela abajo en los comentarios. Intentaré contestaros lo antes posible.
Y eso es todo por hoy. Espero que con lo comentado en el post tengáis suficiente para moveros por QMF y que al menos os sirva para poder almacenar (y recuperar posteriormente) vuestras queries más importantes.
Saludos.
En su día ya estuvimos viendo la instrucción SAVE de QMF, que nos permitía guardar cualquier tipo de código que tuviésemos escrito en el menú DRAW. Junto a ella, como veremos a continuación, tenemos otros otros dos comandos que nos van a venir muy bien a la hora de reutilizar nuestras queries de uso más frecuente. Se trata de DISPLAY QUERY y de LIST QUERIES.
¿Cómo recuperar una query en QMF?
Una vez almacenada la información, la siguiente cuestión que se nos plantearía es cómo recuperar la query en el momento en el que lo deseemos. Obviamente, no tendría mucho sentido almacenar el código si no pensamos usarlo nunca más con posterioridad.
En este entorno, para realizar la acción de recuperar la query en QMF disponemos del comando DISPLAY. Para poder usarlo, en primer lugar tendremos que posicionarnos en la ventana 6=DRAW de la herramienta QMF, tal y como hicimos a la hora de guardar el código.
Una vez aquí, en la línea COMMAND tendremos que incluir el comando DISPLAY QUERY.
COMMAND ===> DISPLAY QUERY EJEMPLO
Pulsamos INTRO y se nos deplegará la siguiente ventana.
Como se puede apreciar, se trata del mismo código que previamente habíamos almacenado con el comando SAVE. Una vez recuperada, esta declaración ya se podría ejecutar del mismo modo que se haría con cualquier otra query de QMF.
Listar todas las queries almacenadas en QMF
Imaginaos que llega un momento en el que tenéis almacenadas 50 queries en vuestro QMF y, por la razón que sea, un cliente os pide que obtengáis de nuevo un informe cuya query lanzásteis hace más de un año. Lo más probable es que no os acordéis del nombre con el que la guardásteis. Entonces, ¿cómo podríais acceder de nuevo a ella?
Para estos casos vamos a usar el comando LIST, que nos mostrará un listado de todas las queries que nuestro usuario tiene almacenadas en la base de datos de QMF. De nuevo, para poder usarlo, en primer lugar tendremos que posicionarnos en la ventana 6=DRAW de la herramienta QMF.
Una vez aquí, en la línea COMMAND tendremos que incluir el comando LIST QUERIES.
COMMAND ===> LIST QUERIES
Pulsamos INTRO y se nos deplegará la siguiente ventana.
Como vemos, en esta pantalla aparecen las queries que previamente he almacenado en QMF con mi usuario.
A continuación, si queremos recuperar el código de alguno de los objetos SQL listados, lo único que tendremos que hacer es usar el comando DISPLAY en la columna ACTION. De este modo, se recuperará el contenido de la query de la misma forma que con el comando DISPLAY QUERY que hemos examinado anteriormente.
--------Dates--------
Action Name Owner Modified Last Used
DISPLAY EJEMPLO JJ00917 2015-10-06 2015-10-07
Esta sería el método estándar para recuperar una query de nuestra base de datos de QMF siempre que no recordemos el nombre con el que la almacenamos en su día.
Almacenar y recuperar queries en QMF
En principio, con los comandos revisados, ya podríamos operar de una manera básica con la base de datos de QMF. Las instrucciones SAVE, DISPLAY y LIST nos permitirán almacenar las queries que vayamos creando y recuperarlas siempre que tengamos necesidad de ellas (independientemente de que nos encontremos ante un tratamiento con la instrucción SELECT, con UPDATE, con INSERT o con DELETE).
Por supuesto, existen más comandos QMF que los aquí mencionados, pero con estas 3 instrucciones ya podremos sobrevivir en el entorno. En un futuro, en un nuevo post, intentaré esbozar una visión global de cuáles son todos los comandos disponibles para esta herramienta.
Aunque siempre habrá queries que sólo queramos usar una vez y que puedan ser desechadas tras su uso, lo importante es que tengamos la posibilidad de reutilizar fácilmente las queries que deban ser ejecutadas periódicamente. Esa función podrá ser realizada de forma eficiente con las instrucciones QMF revisadas hoy.
En principio, siguiendo los pasos aquí comentados no deberíais tener problemas a la hora de trabajar en el entorno. De todas formas, cualquier problema o duda que os surja, ya sabéis que podéis dejármela abajo en los comentarios. Intentaré contestaros lo antes posible.
Y eso es todo por hoy. Espero que con lo comentado en el post tengáis suficiente para moveros por QMF y que al menos os sirva para poder almacenar (y recuperar posteriormente) vuestras queries más importantes.
Saludos.
Suscribirse a:
Entradas (Atom)



















