✒️Las recomendaciones para desarrollar aplicaciones ABAP en SAP HANA
Las recomendaciones para desarrollar aplicaciones ABAP en SAP HANA
1 Tips prácticos importantes al desarrollar aplicaciones ABAP en SAP HANA
Muchos escenarios de uso implican el acceso a grandes conjuntos de datos en tiempo real. Una comprensión sólida de pautas y técnicas para lograr un rendimiento óptimo es esencial.
Analizaremos algunos consejos prácticos sobre temas importantes al desarrollar aplicaciones ABAP en SAP HANA dividiéndolo en 2 áreas:
- Recomendaciones generales: Detalles que debemos considerar para la migración y optimización de los programas ABAP.
- Pautas de performance: La velocidad de ejecución de los programas, naturalmente, desempeña un papel crucial en el contexto de SAP HANA.
2.1 Almacenamiento por columnas vs almacenamiento por filas
- Column store: Es mas eficiente para analizar datasets grandes y provee mejor compresión. Tablas que contenga datos de aplicación deben ser guardados en Column Store ya que seguramente en un futuro será utilizada en analíticos. A menos que haya una razón de peso para elegir Row Store, SAP recomienda que sea este el que se utilice.
- Row Store: Cuando una tabla es accesada principalmente mediante ejecuciones DML (inserts, updates, deletes) y manejan tiempos críticos en sus accesos de escritura debes utilizar este tipo de Store. Cabe señalar que estas tablas son tipicamente accesadas con SELECT SINGLE.
2.2 Implementaciones específicas de SAP HANA
En el desarrollo de ABAP en SAP HANA, debemos distinguir dos escenarios:
- Implementaciones independientes de BD (OpenSQL o vistas ABAP CDS). Aquí no tenemos que considerar nada especial desde la perspectiva de la logística del software. Utilizamos SAP HANA como cualquier base de datos pero nos beneficiamos de la alta velocidad de procesamiento.
- Implementaciones usando funciones específicas de SAP-HANA (NativeSQL, HANA CDS, Column Views o procedimientos almacenados). Inicialmente aquí aplican las mismas implicaciones habituales que cuando definíamos código específico para bases de datos mediante SQL nativo o Hints.
Es dificil dar una recomendación general sobre cuando utilizar una implementación de base de datos específica, cada caso se debe analizar pero sugerimos las siguientes pautas:
- Primero OpenSQL, después Native: Siempre que sea posible utiliza OpenSQL y vistas ABAP CDS. La integración con el ambiente de desarrollo y tiempo de ejecución de ABAP brinda múltiples ventajas.
- Primero Administrado, después Administrado en BD: Comienza utilizando ABAP database procedures antes de utilizar los de SAP-HANA.
2.3 Recomendaciones para la migración
Una regla básica es que las aplicaciones ABAP son totalmente compatibles pero debemos tener en cuenta algunos puntos importantes:
- Código ABAP dependiente de BD: Si tu aplicación tiene código que depende de una BD específica, como SQL nativo mediante instrucciones EXEC SQL, Database Hints o ADBC interface, obviamente necesitarás revisarlo como en cualquier migración y ajustarlo para SAP HANA en caso de ser necesario.
- Conversión de tablas POOL y CLUSTER: Al convertir las tablas cluster y pool en transparentes pueden surgir problemas si confiabamos en que este tipo de tablas conllevaban un ordenamiento implícito. Este ordenamiento se ha perdido al convertirse en tablas transparentes así que agrega SORT u ORDERBY donde lo necesites.
- Comportamiento de sentencias SORT: Debido al funcionamiento de las BD clásicas, en ocasiones tenemos segmentos de código que dependen de un ordenamiento implicito ya que sabemos que la tabla es leída en base a como fue insertada o en base a un índice, por ejemplo el ID mas alto es el registro mas nuevo. Al migrar no puedes dar esto por hecho, HANA es orientado a columnas, no renglones así que agrega SORT u ORDERBY donde lo necesites.
3. Pautas de performance
Existen 5 reglas de oro cuyo objetivo es optimizar la programación de bases de datos, vamos a verlas a detalle y como cambian gracias a SAP HANA.
3.1 Mantener el conjunto de resultados lo mas pequeño posible.
Se tienen 3 posibles medidas a tomar:
- Uso de cláusula WHERE: Utiliza esta instrucción para leer solo los registros que realmente necesitas. Esto es aun mas importante en tablas que se sabe que crecerán con el tiempo ya que cada vez se moverá una mayor cantidad de registros.
- Uso de cláusula HAVING: Utiliza esta instrucción cuando tienes GROUPBYs y deseas obtener solo ciertos grupos condicionando en base a los valores agregados.
- Revisar que se transfieran solo las filas requeridas: Nunca deberías llegar hasta el AS ABAP datos que no necesitas. Si haces una consulta SQL para después eliminar registros en ABAP, entonces debes revisar si es viable utilizar un WHERE y evitar el eliminado posterior. La sentencia CHECK también puede indicar la transferencia de demasiadas filas.
3.2 Mantener el conjunto de datos transferido lo mas pequeño posible
La segunda regla implica transferir la menor cantidad posible de datos entre la BD y el AS. Debemos influir en el número de filas y columnas seleccionadas mediante restricciones que van mas allá de la condición WHERE.
Es similar a la primer regla pero aquí veremos otras posibles medidas que se pueden considerar después de aplicar la regla 1:
- Usando la instrucción UP TO n ROWS: Para obtener solo un cierto número de registros que cumplan las condiciones. Tal vez tienes un LOOP que rompes después de leer los 10 registros con mayor importe pero lo correcto es agregar un UP TO n ROWS.
- Trabajando con DISTINCT: Esta instrucción debe usarse para eliminar entradas duplicadas. En vez de ordenar un SORT BY en una tabla interna junto con DELETE ADJACENT DUPLICATES debes considerar modificar el OpenSQL para agregar un DISTINCT.
- Reduciendo el número de columnas: Evitar completamente el * en tus SELECT. La única razón para usar * junto con INTO CORRESPONDING FIELDS OF es que el esfuerzo de mapear las columnas una por una sea demasiado grande y la cantidad de registros a obtener sea muy pequeña ya que considera que esto implica que se esta trayendo todas las columnas.
- Usando funciones de agregación: Si solo ocupas la información para cálculos es mejor realizar ese procesamiento en la BD y transferir solo los resultados. Se dispone de COUNT, MIN, MAX, SUM y AVG.
- Realizando correctamente las revisiones de existencia: No utilices un SELECT COUNT(*) para saber si existe un registro, mejor utiliza un SELECT field INTO variable con un UP TO 1 ROWS y revisas el resultado de SY-SUBRC.
- Modificando solo las columnas requeridas: Cuando utilices la sentencia UPDATE haz uso de la sentencia SET para indicar que columnas necesitas modificar. Cuando se usan workareas es común que se transfiera todo incluyendo columnas que no sufrieron cambios.
3.3 Reducir el número de ejecuciones de consulta
Esta regla recomienda disminuir el número de llamadas a la BD ya que cada sentencia implica cierto grado de esfuerzo de procesamiento. Por ejemplo: la declaración y parámetros se transfieren a la base de datos donde todo es analizado en cuanto a síntaxis y revisa si existe en caché o la almacena si es la primera vez, después revisa autorizaciones y la existencia de los objetos en la base de datos (tablas, vistas, etc.) y si todo sale bien entonces los resultados de la consulta son transferidos de regreso. Y esto para cada llamada.
Esta regla permite disminuir el consumo de CPU y tiene una prioridad mas alta en SAP HANA que para otras bases de datos ya que el esfuerzo involucrado en la ejecución de una declaración es ligeramente mas alto en SAP HANA que en las BD clásicas aunque se piensa optimizar en el futuro.
Para ello, podemos considerar lo siguiente:
- Usar operaciones en bloque en lugar de individuales: Cuando lees una tabla, utiliza de preferencia la instrucción INTO TABLE; cuando escribes a una tabla utiliza una tabla interna para pasar todos los datos en bloque. Evita en lo posible los bucles SELECT ... ENDSELECT que si bien es capaz de ir transfiriendo en bloques es ineficiente comparado con traer todo de una sola vez. Cuando se trate de accesos de escritura, debemos confiar siempre que sea posible en realizarlas con tablas internas completas ya que de esa forma la base de datos puede realizar mas optimizaciones que si lo haces registro por registro.
- No realices múltiples accesos: Asegurate de no accesar repetidamente a la misma información. No hagas un SELECT SINGLE para revisar si existe y después aplicar un DELETE, mejor haz un DELETE con una cláusula WHERE apropiada.
- No utilizar LOOPS con SELECT ... ENDSELECT anidados: Recordemos que en este caso, el SELECT interno se realizará tantas veces como registros regrese el SELECT externo. Si el objetivo es mezclar información, recomendamos:
- Views: Dependen del plan de ejecución pero generalmente son mas rápidas que un loop anidado.
- Joins: Generalmente si se logra hacer un JOIN implicará una sola llamada.
- FOR ALL ENTRIES: Aquí, el SELECT externo se graba en una tabla interna que después se utiliza para ejecutar el SELECT interno. Es mas rápido debido a que la consulta se ejecuta por bloques y no uno por uno.
- Subqueries: Permiten acceder múltiples tablas en una sola llamada. Algo a considerar es que esta opción es útil cuando el subquery solo se utiliza para limitar resultados.
- No ejecutar sentencias SELECT o SELECT SINGLE dentro de ciclos: Este escenario es candidato a FOR ALL ENTRIES y solo se debe asegurar que la tabla interna a utilizar no este vacía o traerá toda la información lo cual es terrible y además hay que revisar que no contenga duplicados para evitar consultas duplicadas.
- Buffers: Utilizar el table buffer o algún otro contribuye a minimizar el número de sentencias SQL enviadas a la BD.
3.4 Minimizar el esfuerzo de búsqueda
Esta regla trae implicito el tener índices en la BD y saber utilizarlos desde las sentencias SELECT. Un indice es un conjunto de campos de una tabla que son copiados en una secuencia odenada a otra estructura. Hay índices primarios (las llaves) y secundarios (generalmente usados para rendimiento aunque también pueden tener motivos semánticos al marcar campos como únicos). La formulación correcta de cláusulas WHERE y HAVING y una definición de índice secundario adecuada puede minimizar por mucho el esfuerzo de búsqueda porque solo se debe leer una parte de los datos.
Se recomienda:
- En cuanto a creación:
- Crear indices secundarios solo en tablas donde es mas importante el acceso de lectura que el de escritura ya que cada índice creado debe mantenerse para los accesos de escritura.
- El número de índices y campos en los índices debe mantenerse tan pequeño como sea posible. De lo contrario se requiere mas esfuerzo para cambiar los accesos y el optimizador es mas probable que tome decisiones erróneas.
- Los campos deben estar, dentro de lo posible en solo un índice. Deben evitarse solapamientos.
- Los campos en un índice deben ser campos muy comunmente utilizados y los que tienen mas probabilidades de ser consultados con el operador = deben estar al principio del índice.
- En cuanto a consultas:
- El operador = ó EQ además de AND son soportados con gran eficiencia. También es recomendada la sentencia IN.
- Evitar condiciones negativas porque no son soportadas con tanta eficiencia como las positivas.
- Si no puedes completar todos los campos del índice, asegurate que cumples hasta donde te sea posible. Si no logras ir cumpliendo con los campos del índice en el orden creado es muy posible que no se utilice.
- Particularmente en HANA:
- Se tienen dos índices: invertido y compuesto. El primero es para una sola columna y el segundo para varias.
- Los compuestos tienen un requisito de memoria mas alto por lo que se recomienda trabajar lo mas posible con índices invertidos. Además, los índices compuestos deben crearse solo en casos excepcionales donde se sabe que datos de distintas columnas se correlacionan de tal forma que solo ciertas combinaciones son selectivas.
- El mantenimiento de los índices aumenta los costos de acceso de escritura en SAP HANA. Sin embargo, estos costos son significativamente menores para índices invertidos que para compuestos.
- Cabe señalar que debido a que HANA utiliza COLUMN STORE es muy posible que no necesites muchos de los índices que utilizabas en una BD tradicional.
- En principio, solo se deben crear índices adicionales si los tiempos de acceso son insuficientes sin un índice.
3.5 Reducir la carga en la base de datos
Esta regla resume las 4 anteriores y recomienda disminuir la carga que le damos al servidor de BD. Esta regla conlleva que la base de datos solo realice lo que se necesite, por ejemplo hemos dicho que una fortaleza de SAP HANA es su capacidad de realizar cálculos complejos sobre grandes conjuntos de datos pero no tiene sentido ejecutar dichos cálculos en repetidas ocasiones para los mismos datos.
Tenemos 3 posibles herramientas para lograrlo:
- Utilizando buffers: No hay cambios en este sentido, un buffer sigue siendo mas rápido que acceder a la BD, si tienes una aplicación que los utilice o donde pueden utilizarse, adelante ya que puede ser hasta 10 veces mas rápido que el acceso a base de datos. Ejemplos de buffer cross-user: Tabble buffer, shared objects, shared memory, shared buffer. Ejemplos de buffer specific-user: tablas internas, abap memory, sap memory.
- Ordenando: Si no puedes utilizar un índice para ordenar tu información, es aceptable considerar realizarlo en el ABAP AS. Un caso a considerar es que el ordenamiento se requiere sobre un conjunto grande de datos pero para calcular un resultado menor, en cuyo caso el ordenamiento debe realizarse en la base de datos (por ejemplo ordenar para determinar los 5 mejores clientes en relación con valor de pedidos).
- Evitar accesos idénticos: Pues eso, no vayas dos veces por la misma información, utiliza tablas internas o buffers.
TIPS:
- Al diseñar la aplicación debemos tener en cuenta las siguientes preguntas: ¿Hay sistemas con una base de datos distinta en tu escenario?, ¿Cuán fundamental son estas funciones específicas para tu aplicación?, ¿Esta funcionalidad será accesada solo mediante aplicaciones ABAP o se usarán otros canales?...
- El inspector de código nos proporciona la verificación Find Select For Pool/Cluster Tab without ORDER BY para que podamos encontrar rápida y facilmente estos puntos críticos en nuestros desarrollos ABAP.
 
 
 
2 Agradecimientos:
Han agradecido este aporte: Martín Gómez Rodríguez, Jesús Quiñonez López
Sobre el autor
Publicación académica de Abraham Humberto Noriega Cabrera, en su ámbito de estudios para el Máster ABAP for HANA.
Abraham Humberto Noriega Cabrera
Profesión: Ingeniero Sistemas Computacionales - Mexico - Legajo: WO62V
✒️Autor de: 14 Publicaciones Académicas
🎓Egresado del módulo:
Disponibilidad Laboral: FullTime
Presentación:
Ingeniero en sistemas computacionales con experiencia en análisis, desarrollo e implementación de sistemas. he tenido el gusto de participar en implementaciones tanto locales como a nivel estatal.
Certificación Académica de Abraham Noriega