{"id":69,"date":"2025-04-29T23:47:50","date_gmt":"2025-04-30T02:47:50","guid":{"rendered":"https:\/\/dedelberg.com.ar\/?p=69"},"modified":"2025-04-29T23:51:03","modified_gmt":"2025-04-30T02:51:03","slug":"indices-personalizados-en-sap-hana","status":"publish","type":"post","link":"https:\/\/dedelberg.com.ar\/index.php\/2025\/04\/29\/indices-personalizados-en-sap-hana\/","title":{"rendered":"\u00cdndices Personalizados en SAP HANA"},"content":{"rendered":"\n<p class=\"has-medium-font-size\">En el mundo SAP, el rendimiento lo es todo. Y cuando hablamos de SAP HANA, muchos conf\u00edan plenamente en su motor inteligente para optimizar consultas sin necesidad de intervenir. Pero, \u00bfqu\u00e9 pasa cuando el rendimiento no es el esperado?<\/p>\n\n\n\n<p>SAP HANA est\u00e1 dise\u00f1ado para ofrecer alto rendimiento sin necesidad de \u00edndices secundarios, gracias a su arquitectura in-memory, el almacenamiento orientado a columnas, la compresi\u00f3n avanzada y el paralelismo masivo. Sin embargo, existen escenarios bien definidos donde la creaci\u00f3n de \u00edndices personalizados puede mejorar significativamente el tiempo de respuesta de las consultas.<\/p>\n\n\n\n<p>Por defecto, HANA utiliza el almacenamiento columnar, lo que permite leer solo las columnas necesarias para cada consulta. Por ejemplo, en una tabla con 150 columnas, una consulta que solo accede a 3 de ellas evita leer el resto, lo que representa una reducci\u00f3n de I\/O y uso de memoria de hasta un 98%. Adem\u00e1s, las columnas homog\u00e9neas se comprimen mejor; en algunos entornos OLAP reales, se logran ratios de compresi\u00f3n de hasta 7:1.<\/p>\n\n\n\n<p>El motor de ejecuci\u00f3n paraleliza autom\u00e1ticamente las operaciones. Una query compleja con m\u00faltiples <code>JOINs<\/code> y agregaciones puede ser distribuida entre 32 n\u00facleos o m\u00e1s, reduciendo el tiempo de ejecuci\u00f3n de minutos a segundos. El optimizador de HANA, adem\u00e1s, analiza estad\u00edsticas de cardinalidad, distribuci\u00f3n de valores, y costo estimado por operador para determinar el mejor plan posible. En este contexto, la creaci\u00f3n manual de \u00edndices es innecesaria en la mayor\u00eda de los casos.<\/p>\n\n\n\n<p>No obstante, hay situaciones donde los \u00edndices personalizados s\u00ed ofrecen una ventaja tangible. Consideremos algunos ejemplos:<\/p>\n\n\n\n<p>Supongamos una consulta como:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>SELECT p.nombre, v.total \nFROM ventas v \nJOIN productos p ON v.id_producto = p.id \nWHERE p.categoria = 'Servicios';\n<\/code><\/code><\/pre>\n\n\n\n<p>Si la tabla <code>productos<\/code> tiene 1 mill\u00f3n de registros pero solo 6 categor\u00edas posibles, un \u00edndice en <code>p.categoria<\/code> puede acelerar significativamente la filtraci\u00f3n post-join. En pruebas de laboratorio con tablas de 10M de registros, la creaci\u00f3n de un \u00edndice en una columna de 10 valores \u00fanicos redujo el tiempo de ejecuci\u00f3n de 950 ms a 210 ms.<\/p>\n\n\n\n<p>Si m\u00faltiples consultas usan:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\u2026 JOIN logs l ON l.usuario_email = u.email<\/code><\/pre>\n\n\n\n<p>Y <code>usuario_email<\/code> no est\u00e1 indexado, el optimizador puede fallar en estimar correctamente el costo. Un \u00edndice en <code>l.usuario_email<\/code> puede reducir el tiempo de b\u00fasqueda de un hash join de O(n) a O(log n). En una tabla de 5 millones de filas, se ha observado una mejora del 65% en la latencia.<\/p>\n\n\n\n<p>En sistemas h\u00edbridos OLTP\/OLAP donde una aplicaci\u00f3n busca datos como:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SELECT * FROM pedidos WHERE codigo_interno = 'ABX-9211';\n<\/code><\/pre>\n\n\n\n<p>Si <strong>codigo_interno <\/strong>no forma parte de la clave primaria, HANA deber\u00e1 escanear toda la columna (full column scan). Crear un \u00edndice hash puede hacer que la b\u00fasqueda pase de 400 ms a &lt;10 ms en tablas medianas (500.000 filas).<br><br>Cuando una consulta contiene:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>WHERE YEAR(fecha_factura) = 2024<\/code><\/pre>\n\n\n\n<p>El \u00edndice tradicional en <code>fecha_factura<\/code> no se aprovecha porque el optimizador no puede usarlo directamente sobre una funci\u00f3n. Una soluci\u00f3n eficiente es crear un <strong>\u00edndice calculado<\/strong> sobre <code>YEAR(fecha_factura)<\/code>, lo que permite a HANA utilizarlo para filtrar antes de procesar el resto. En una tabla de 2M de facturas, esto puede reducir la latencia de 1.8 s a 230 ms.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading has-medium-font-size\">Riesgos asociados a la creaci\u00f3n de \u00edndices<\/h2>\n\n\n\n<p>Crear \u00edndices sin un an\u00e1lisis puede impactar negativamente en el correcto y fluido funcionamiento del sistema HANA, ya que cada \u00edndice ocupa espacio adicional. Un \u00edndice en una tabla de 10M filas puede requerir entre 100 MB y 1 GB, seg\u00fan la cardinalidad y tipo de datos, las operaciones <code>INSERT<\/code>, <code>UPDATE<\/code> y <code>DELETE<\/code> se vuelven m\u00e1s lentas, ya que deben actualizar cada \u00edndice. En pruebas internas, el <code>INSERT<\/code> de 100.000 registros aument\u00f3 de 4 a 9 segundos al agregar 3 \u00edndices. Esto sin contar que mantener demasiados \u00edndices es engorroso y requiere un esfuerzo constante.<\/p>\n\n\n\n<h2 class=\"wp-block-heading has-medium-font-size\">Mis recomendaciones<\/h2>\n\n\n\n<p>SAP HANA ofrece un rendimiento excelente por dise\u00f1o. Pero como todo sistema, tiene puntos de optimizaci\u00f3n cuando se enfrenta a patrones espec\u00edficos de acceso. Los \u00edndices personalizados deben usarse como herramientas quir\u00fargicas, no como soluciones universales. El conocimiento del modelo de datos, los patrones de consulta y las cargas del sistema es lo que permite tomar decisiones correctas. Crear un \u00edndice debe ser el resultado de un diagn\u00f3stico, no un reflejo autom\u00e1tico. Cuando se aplican con criterio, los resultados son medibles, sostenibles y valiosos.<\/p>\n\n\n\n<p>Yo recomiendo siempre trabajar sobre los datos reales. Es decir, identificar las consultas lentas utilizando Performance Analysis Mode en HANA Studio o PlanViz, buscar los full scans que puedan existir en las consultas o los joins mal optimizados. <\/p>\n\n\n\n<p>Una vez identificadas las consultas mas lentas, lo ideal es comenzar a reescribir las consultas. A veces peque\u00f1os cambios pueden hacer grandes diferencias. Luego, si no hay lugar a la reescritura, ya sea porque la consulta es std, o porque est\u00e1 optimizada, crear los \u00edndices necesarios en el sistema.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>En el mundo SAP, el rendimiento lo es todo. Y cuando hablamos de SAP HANA, muchos conf\u00edan plenamente en su motor inteligente para optimizar consultas sin necesidad de intervenir. Pero, \u00bfqu\u00e9 pasa cuando el rendimiento no es el esperado? SAP HANA est\u00e1 dise\u00f1ado para ofrecer alto rendimiento sin necesidad de \u00edndices secundarios, gracias a su [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":70,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[5,6],"class_list":["post-69","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-sin-categoria","tag-hana","tag-sap"],"_links":{"self":[{"href":"https:\/\/dedelberg.com.ar\/index.php\/wp-json\/wp\/v2\/posts\/69","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dedelberg.com.ar\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dedelberg.com.ar\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dedelberg.com.ar\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dedelberg.com.ar\/index.php\/wp-json\/wp\/v2\/comments?post=69"}],"version-history":[{"count":1,"href":"https:\/\/dedelberg.com.ar\/index.php\/wp-json\/wp\/v2\/posts\/69\/revisions"}],"predecessor-version":[{"id":73,"href":"https:\/\/dedelberg.com.ar\/index.php\/wp-json\/wp\/v2\/posts\/69\/revisions\/73"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/dedelberg.com.ar\/index.php\/wp-json\/wp\/v2\/media\/70"}],"wp:attachment":[{"href":"https:\/\/dedelberg.com.ar\/index.php\/wp-json\/wp\/v2\/media?parent=69"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dedelberg.com.ar\/index.php\/wp-json\/wp\/v2\/categories?post=69"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dedelberg.com.ar\/index.php\/wp-json\/wp\/v2\/tags?post=69"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}