Desarrollando en Cobol y Natural sobre Plataforma Mainframe

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.

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.

No hay comentarios:

Publicar un comentario

Related Posts Plugin for WordPress, Blogger...