Rendimiento de las nuevas funciones nativas en Teradata 14

Una de las cosas menos agradables a la hora de trabajar con Teradata ha sido siempre una cierta falta de versatilidad. Entre esta falta de versatilidad se encontraba el limitado repertorio de funciones, que hacía incómodo y a veces demasiado alambicado conseguir ciertas funcionalidades que en otros RDBMS’s (¿alguien dijo Oracle?) se obtienen de forma concisa e intuitiva con el uso, precisamente, de funciones.

Teradata llenaba el hueco con la posibilidad de utilizar UDFs (User Defined Functions), que no eran otra cosa que rutinas escritas en C que podían -tras ser compiladas- ser llamadas desde funciones ‘envoltorios’ SQL. Teradata también proporcionaba el código fuente de unas cuantas funciones que solían corresponderse con funciones Oracle, ampliamente utilizadas en dichos entornos y que prácticamente todo el mundo conoce.

Pero esto, con ser una solución, no era la mejor. El rendimiento no solía ser óptimo y la laboriosidad de su desarrollo era otro factor en contra. Hay muchos ejemplos de este tipos de funciones: oReplace(), oTranslate(), Instr()…

Teradata 14 viene con un montón de nuevas funciones nativas, llamadas “Embedded Services System Functions” (ya hemos comentado algunas aquí) y desde luego no se oculta su origen ‘oraclero’: NVL(), NVL2(), TO_DATE(), TO_CHAR(), TO_NUMBER(), ROUND(), TRUNC(), LPAD(), RPAD()… La pregunta es: ¿cuánto mejor son en rendimiento respecto de sus “hermanas” UDFs?

Pues la mejor forma de verlo es remangarse y poner manos a la obra:

 BTEQ -- Enter your SQL request or BTEQ command:
CREATE MULTISET TABLE CARLOS.PRUEBAOFUNCTION
(
   COLUMNA1 VARCHAR(9),
   COLUMNA2 VARCHAR(9),
   COLUMNA3 VARCHAR(9)
)
PRIMARY INDEX ( COLUMNA1 )
;

 *** Table has been created.
 *** Total elapsed time was 1 second.

 BTEQ -- Enter your SQL request or BTEQ command:
INSERT INTO CARLOS.PRUEBAOFUNCTION
SELECT c.COLUMNA0 COLUMNA1,
       CAST(OTRANSLATE(c.COLUMNA0,
                       '1234567890ABCDEFGHIJKLMNÑOPQRSTUVWXYZabcdefghijklmnñopqrstuvwxyz _-',
                       '1234567890ABCDEFGHIJKLMNÑOPQRSTUVWXYZABCDEFGHIJKLMNÑOPQRSTUVWXYZ') AS VARCHAR(9)) COLUMNA2,
       CAST(OTRANSLATE(c.COLUMNA0,
                       '1234567890ABCDEFGHIJKLMNÑOPQRSTUVWXYZabcdefghijklmnñopqrstuvwxyz _-',
                       '9999999999XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX') AS VARCHAR(9)) COLUMNA3
  FROM CARLOS.PRUEBA01 c
 WHERE c.COLUMNA0 IS NOT NULL
;

 *** Insert completed. 62898886 rows added.
 *** Total elapsed time was 5 minutes and 23 seconds.

Hasta aquí el funcionamiento de una típica funcion Oracle en forma de UDF (escrita en C). Una doble llamada a oTranslate() sobre dos columnas en un INSERT…SELECT de unos 63 millones de filas nos lleva 5 minutos y 23 segundos.

Vamos ahora con el mismo proceso, pero esta vez llamando a la función nativa:

 BTEQ -- Enter your SQL request or BTEQ command:

DELETE FROM CARLOS.PRUEBAOFUNCTION;

 *** Delete completed. 62898886 rows removed.
 *** Total elapsed time was 1 second.

 BTEQ -- Enter your SQL request or BTEQ command:
INSERT INTO CARLOS.PRUEBAOFUNCTION
SELECT c.COLUMNA0 COLUMNA1,
       CAST(TD_SYSFNLIB.OTRANSLATE(c.COLUMNA0,
                       '1234567890ABCDEFGHIJKLMNÑOPQRSTUVWXYZabcdefghijklmnñopqrstuvwxyz _-',
                       '1234567890ABCDEFGHIJKLMNÑOPQRSTUVWXYZABCDEFGHIJKLMNÑOPQRSTUVWXYZ') AS VARCHAR(9)) COLUMNA2,
       CAST(TD_SYSFNLIB.OTRANSLATE(c.COLUMNA0,
                       '1234567890ABCDEFGHIJKLMNÑOPQRSTUVWXYZabcdefghijklmnñopqrstuvwxyz _-',
                       '9999999999XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX') AS VARCHAR(9)) COLUMNA3
  FROM CARLOS.PRUEBA01 c
 WHERE c.COLUMNA0 IS NOT NULL
;

 *** Insert completed. 62898886 rows added.
 *** Total elapsed time was one minute and 7 seconds.

 BTEQ -- Enter your SQL request or BTEQ command:

El resultado es claro: la sentencia con la llamada a la UDF tarda cinco veces el tiempo de la sentencia con llamada a la función nativa.

Así pues, si tienes llamadas a UDFs que ahora son cubiertas por éstas nuevas “Embedded Services System Functions”, ya estás tardando en cambiarlas.

Una cosa más: Teradata resuelve una función siguiendo un orden de búsqueda: Base de datos actual, SYSLIB y TD_SYSFNLIB (que es donde están las nuevas funciones nativas), por lo que si no vas a cualificar la llamada (haciendo, por ejemplo, TD_SYSFNLIB.OREPLACE()) deberás asegurarte que no existe ninguna UDF con el mismo nombre ni en la base de datos actual ni en SYSLIB.

Saludos.

Carlos.

Anuncios

One Response to Rendimiento de las nuevas funciones nativas en Teradata 14

  1. […] hemos hablado aquí de las nuevas funciones nativas de Teradata 14 (“Embedded Services System Functions”) y de cómo nos solucionan algunos problemas de […]

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: