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.

Una respuesta a 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: