Docsity
Docsity

Prepara tus exámenes
Prepara tus exámenes

Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity


Consigue puntos base para descargar
Consigue puntos base para descargar

Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium


Orientación Universidad
Orientación Universidad


Tablas internas en abap, Resúmenes de Derecho

Uso de tablas internas en abap para sy mejor consumo

Tipo: Resúmenes

2023/2024

Subido el 25/05/2026

miguel-arbieto
miguel-arbieto 🇨🇱

1 documento

1 / 22

Toggle sidebar

Esta página no es visible en la vista previa

¡No te pierdas las partes importantes!

bg1
Guia tecnica ABAP - Performance de tablas internas
Documento tecnico - SAP ABAP / S/4HANA - Uso interno de equipos de desarrollo
Guia tecnica profesional
Tablas internas ABAP: performance,
memoria y arquitectura
STANDARD, SORTED, HASHED, claves primarias/secundarias y expresiones modernas ABAP
7.4+
Nivel: Arquitecto ABAP / Senior Developer
Version: 1.1 ampliada - Mayo 2026
Basado principalmente en SAP ABAP Keyword Documentation, SAP Help Portal y buenas practicas modernas para ABAP
7.4+, ABAP Cloud y S/4HANA.
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16

Vista previa parcial del texto

¡Descarga Tablas internas en abap y más Resúmenes en PDF de Derecho solo en Docsity!

Guia tecnica profesional

Tablas internas ABAP: performance,

memoria y arquitectura

STANDARD, SORTED, HASHED, claves primarias/secundarias y expresiones modernas ABAP

Nivel: Arquitecto ABAP / Senior Developer

Version: 1.1 ampliada - Mayo 2026

Basado principalmente en SAP ABAP Keyword Documentation, SAP Help Portal y buenas practicas modernas para ABAP

7.4+, ABAP Cloud y S/4HANA.

Indice ejecutivo

1. Resumen ejecutivo y matriz de decision.

2. Modelo tecnico de tablas internas: categorias, claves y acceso.

3. Comparativa de performance: complejidad, memoria, insercion, lectura y borrado.

4. Uso correcto de READ TABLE, LOOP, table expressions, FILTER, REDUCE, FOR y VALUE.

5. Casos empresariales, anti-patrones y versiones optimizadas.

6. Performance tuning, costos ocultos de copia y recomendaciones finales.

7. Catalogo ampliado: creacion y uso de STANDARD, SORTED y HASHED con claves secundarias.

Nota de alcance: los valores de Big O son aproximaciones de arquitectura. La documentacion SAP describe busqueda lineal en
STANDARD, busqueda binaria/logaritmica en SORTED y algoritmo hash/consumo constante en HASHED para accesos por clave
aplicables. Los microbenchmarks incluidos son plantillas y resultados cualitativos esperados; deben ejecutarse en el landscape real para
medir tiempos absolutos.

1. Resumen ejecutivo

En ABAP moderno, la seleccion de la categoria de tabla interna es una decision de arquitectura, no un detalle de sintaxis.

Una tabla interna puede consumir la mayor parte del tiempo de CPU de un proceso de dialogo, batch, interfaz o job de

migracion cuando se usa como cache, indice, buffer, staging area o estructura de agregacion. La diferencia entre un

acceso lineal repetido y un acceso por hash o por arbol ordenado puede convertir un algoritmo O(n*m) en O(n) u O(n log

n).

La regla principal es disenar la tabla segun el patron dominante de acceso: lectura puntual por clave, recorrido por rango,

insercion masiva, orden estable, deduplicacion, agrupacion o transformacion funcional. La recomendacion profesional es

declarar la clave de forma explicita y evitar depender del DEFAULT KEY, salvo que el tipo sea trivial y el impacto sea

irrelevante.

Necesidad dominante Tipo recomendado Razon tecnica Riesgo principal Lectura puntual frecuente por clave completa unica

HASHED TABLE WITH UNIQUE
KEY

Acceso promedio O(1) por hash. Evita SORT + BINARY SEARCH repetido. Mayor memoria; no hay acceso por indice ni rangos eficientes. Lectura por rangos, prefijos o LOOP WHERE por clave ordenada SORTED TABLE, o secondary sorted key Acceso inicial O(log n) y recorrido secuencial eficiente por el orden. Insercion mas costosa; clave y orden deben alinearse con el WHERE. Carga secuencial, procesamiento completo, pocas busquedas

STANDARD TABLE WITH

EMPTY KEY o clave explicita Append barato y acceso por indice. Menor overhead de indices. Busquedas por clave son lineales si no se usa clave secundaria. Mismo dataset con multiples patrones de lectura STANDARD/SORTED con secondary sorted/hash keys Permite optimizar accesos alternativos sin duplicar tablas. Cada clave secundaria consume memoria y costo de mantenimiento. Deduplicacion estricta por identificador HASHED o SORTED WITH UNIQUE KEY El runtime impide duplicados a nivel de estructura. Dump/excepcion si se inserta duplicado sin control.

2. Modelo tecnico de tablas internas

Una tabla interna tiene tres dimensiones de diseno: tipo de linea, categoria de tabla y claves. La categoria define la

estructura primaria de acceso: STANDARD, SORTED o HASHED. La clave primaria existe para todas las categorias; las

claves secundarias agregan indices optimizados adicionales. En ABAP 7.4+ y S/4HANA, el diseno explicito de claves es

esencial para que READ TABLE, LOOP AT WHERE, FILTER, table expressions y constructores modernos se comporten

de forma predecible y eficiente.

Categoria Propiedad tecnica Acceso por indice Clave primaria Orden fisico/logico Uso tipico STANDARD TABLE Tabla con indice lineal primario. Acceso por clave primaria no optimizado salvo clave secundaria. Si No unica por definicion practica; puede declararse clave no unica o empty key. Orden de insercion o SORT explicito. Staging, colecciones temporales, procesamiento secuencial, resultados de SELECT.

2.3 HASHED TABLE

HASHED TABLE es la estructura recomendada para lectura puntual por clave completa unica. No se debe elegir cuando

el negocio requiere rangos, orden, acceso por indice o duplicados. En caches de material, cliente, condiciones,

autorizaciones o tablas de customizing por clave exacta, suele ser la opcion de menor CPU.

TYPES: BEGIN OF ty_mara_cache, matnr TYPE matnr, mtart TYPE mtart, matkl TYPE matkl, END OF ty_mara_cache. DATA lt_mara_by_matnr TYPE HASHED TABLE OF ty_mara_cache WITH UNIQUE KEY matnr. READ TABLE lt_mara_by_matnr ASSIGNING FIELD-SYMBOL() WITH TABLE KEY matnr = lv_matnr. IF sy-subrc = 0. "Lookup exacto promedio O(1). ENDIF.

3. Claves: UNIQUE, NON-UNIQUE, EMPTY, primarias y secundarias 3.1 UNIQUE KEY

UNIQUE KEY garantiza unicidad estructural. En HASHED TABLE es obligatoria. En SORTED TABLE evita duplicados y

permite lecturas deterministicas por clave completa. Arquitectonicamente se usa cuando duplicar una linea por la clave

seria un error de negocio o de cache.

DATA lt_t001 TYPE HASHED TABLE OF t001 WITH UNIQUE KEY bukrs. INSERT ls_t001 INTO TABLE lt_t001. IF sy-subrc <> 0. "Duplicado: decidir si ignorar, acumular error o reemplazar controladamente. ENDIF. 3.2 NON-UNIQUE KEY

NON-UNIQUE KEY se usa para relaciones 1:n o agrupaciones por clave parcial. Es comun en SORTED TABLE cuando

se requiere LOOP WHERE por sociedad, cliente, material, fecha o estado. En STANDARD TABLE las claves no unicas no

eliminan el costo lineal de lectura por clave primaria; para optimizar se requiere clave secundaria o cambiar la categoria.

DATA lt_bseg_by_account TYPE SORTED TABLE OF ty_open_item WITH NON-UNIQUE KEY bukrs hkont gjahr belnr. LOOP AT lt_bseg_by_account ASSIGNING FIELD-SYMBOL() WHERE bukrs = lv_bukrs AND hkont = lv_hkont. "Eficiente para todos los apuntes de una cuenta. ENDLOOP. 3.3 EMPTY KEY

EMPTY KEY significa que la tabla no tiene componentes de clave primaria utiles para busqueda semantica. Es

recomendable para STANDARD TABLE usadas como listas puras o resultados temporales, porque evita el DEFAULT

KEY implicito sobre componentes caracter-like y numericos que puede generar comportamiento inesperado. No se debe

usar EMPTY KEY si luego se pretende READ TABLE WITH TABLE KEY semantico.

"Lista pura: correcto. DATA lt_messages TYPE STANDARD TABLE OF bapiret2 WITH EMPTY KEY. "Antip patron: lista con EMPTY KEY usada luego como diccionario.

READ TABLE lt_messages WITH TABLE KEY id = 'Z1' number = '001' TRANSPORTING NO FIELDS. "En una clave primaria vacia, el resultado no representa una busqueda semantica. 3.4 Claves secundarias

Las claves secundarias permiten que la misma tabla tenga indices adicionales. Una secondary sorted key es ideal para

recorridos por rango o WHERE por prefijo. Una secondary hashed key es ideal para lectura puntual por una clave

alternativa unica. Deben declararse solo cuando el volumen y la frecuencia de lectura compensen memoria y

mantenimiento en INSERT, DELETE, MODIFY o cambios de campos clave.

TYPES: BEGIN OF ty_sales, vbeln TYPE vbeln_va, kunnr TYPE kunnr, erdat TYPE erdat, auart TYPE auart, netwr TYPE netwr_ak, END OF ty_sales. DATA lt_sales TYPE STANDARD TABLE OF ty_sales WITH EMPTY KEY WITH UNIQUE HASHED KEY by_vbeln COMPONENTS vbeln WITH NON-UNIQUE SORTED KEY by_customer_date COMPONENTS kunnr erdat. "Lookup puntual por documento. ASSIGN lt_sales[ KEY by_vbeln COMPONENTS vbeln = lv_vbeln ] TO FIELD-SYMBOL(). "Rango por cliente y fecha. LOOP AT lt_sales ASSIGNING FIELD-SYMBOL() USING KEY by_customer_date WHERE kunnr = lv_kunnr AND erdat >= lv_from AND erdat <= lv_to. ENDLOOP. Clave secundaria Ventajas Desventajas Escenario ideal Impacto performance Secondary sorted key Rangos, prefijos, orden estable para LOOP USING KEY. Memoria adicional; mantenimiento en cambios; no siempre mejora si el WHERE no usa prefijo. Reportes por cliente- fecha, sociedad-cuenta, material-centro. Reduce busquedas lineales a O(log n)+k; inserciones/modificacione s tienen costo adicional. Secondary hashed key Lookup exacto por clave alternativa unica. Debe ser unica; no sirve para rangos; mayor overhead. Cache con ID tecnico y tambien clave natural unica. Lectura promedio O(1); costo extra al poblar y mantener tabla. 3.5 Catalogo practico de creacion y uso por tipo de tabla

Esta seccion es una guia operativa para el equipo: muestra como declarar, poblar, leer, recorrer, borrar y decidir cada tipo

de tabla. La idea es que la declaracion de la tabla documente el contrato de acceso. Si el codigo necesita buscar por

varias rutas, declare claves secundarias nombradas; si solo necesita una lista temporal, use STANDARD TABLE WITH

EMPTY KEY.

Decision de diseno STANDARD TABLE SORTED TABLE HASHED TABLE Clave primaria permitida Siempre no unica. Puede ser EMPTY KEY, DEFAULT KEY o componentes explicitos. UNIQUE o NON-UNIQUE por componentes. Obligatoriamente UNIQUE por componentes. Acceso por indice Si: READ/LOOP INDEX, sy-tabix, INSERT INDEX. Si, porque es una index table. No. No usar INDEX ni depender de orden. Claves secundarias Muy utiles para optimizar una lista que tambien se consulta por clave. Utiles para claves alternativas a la clave ordenada principal. Utiles para rangos alternativos o lookup por otra clave unica. Forma recomendada de poblar APPEND/INSERT INTO TABLE, SELECT INTO TABLE, VALUE/FOR. INSERT INTO TABLE para que el runtime ubique posicion. INSERT INTO TABLE. No disenar con APPEND ni indice. Riesgo mas comun READ lineal repetido dentro de LOOP externo. Clave ordenada que no coincide con el WHERE real. Usarla para rangos, duplicados o salida ordenada de negocio.

"Carga masiva: mantiene una sola tabla logica. SELECT vbeln, posnr, kunnr, matnr, erdat, netwr FROM vbap INTO TABLE @lt_items WHERE erdat BETWEEN @lv_from AND @lv_to. "Lookup exacto por documento y posicion: usa secondary hashed key. ASSIGN lt_items[ KEY by_doc_item COMPONENTS vbeln = lv_vbeln posnr = lv_posnr ] TO FIELD-SYMBOL(). IF sy-subrc = 0. "Sin copia; apunta a la linea. ENDIF. "Rango por cliente y fecha: usa secondary sorted key. LOOP AT lt_items ASSIGNING FIELD-SYMBOL() USING KEY by_customer_date WHERE kunnr = lv_kunnr AND erdat >= lv_from AND erdat <= lv_to. ENDLOOP. "Existencia eficiente sin transportar datos. IF line_exists( lt_items[ KEY by_doc_item COMPONENTS vbeln = lv_vbeln posnr = lv_posnr ] ). ENDIF.

Regla tecnica: secondary hashed key para igualdad completa y unica; secondary sorted key para rangos, prefijos, orden y

LOOP WHERE. No declare ambas sobre los mismos campos si no hay un patron real que lo justifique.

"Ejemplo incorrecto: loop externo + READ lineal sobre STANDARD. LOOP AT lt_vbap ASSIGNING FIELD-SYMBOL(). READ TABLE lt_mara_std ASSIGNING FIELD-SYMBOL() WITH KEY matnr = -matnr. "Si lt_mara_std es STANDARD sin secondary key: O(n*m). ENDLOOP. "Version optimizada A: HASHED TABLE dedicada para cache de materiales. DATA lt_mara_hash TYPE HASHED TABLE OF ty_mara_cache WITH UNIQUE KEY matnr. LOOP AT lt_vbap ASSIGNING . ASSIGN lt_mara_hash[ matnr = -matnr ] TO . IF sy-subrc = 0. "O(1) promedio por material. ENDIF. ENDLOOP. "Version optimizada B: STANDARD con secondary hashed key. DATA lt_mara_std2 TYPE STANDARD TABLE OF ty_mara_cache WITH EMPTY KEY WITH UNIQUE HASHED KEY by_matnr COMPONENTS matnr. LOOP AT lt_vbap ASSIGNING . ASSIGN lt_mara_std2[ KEY by_matnr COMPONENTS matnr = -matnr ] TO . ENDLOOP.

3.5.3 Operaciones recomendadas en STANDARD TABLE

Operacion Sintaxis recomendada Cuando usar Observacion de performance

Agregar linea APPEND ls TO lt o INSERT ls INTO TABLE lt Carga secuencial o resultado de transformacion. APPEND es simple para STANDARD; INSERT INTO TABLE generaliza a otros tipos. Leer por indice READ TABLE lt INDEX i ASSIGNING

Paginacion, posicion conocida, ALV temporal. O(1), pero fragil si el orden cambia. Leer por clave secundaria hash lt[ KEY k COMPONENTS f = v ] Lookup exacto alternativo. Promedio O(1), evita tabla duplicada. Recorrer por rango LOOP AT lt USING KEY k WHERE ... Rangos por clave sorted secundaria. O(log n)+k si WHERE alinea con prefijo de k. Borrar por condicion DELETE lt WHERE ... Limpieza simple. Lineal si no usa clave; cuidado con tablas muy grandes.

3.5.4 SORTED TABLE: formas de creacion

SORTED TABLE debe elegirse cuando el orden por clave es parte del algoritmo. El runtime mantiene la tabla ordenada;

por eso no requiere SORT antes de leer por su clave primaria. La clave puede ser unica o no unica.

TYPES: BEGIN OF ty_fi_item, bukrs TYPE bukrs, gjahr TYPE gjahr, hkont TYPE hkont, belnr TYPE belnr_d, buzei TYPE buzei, budat TYPE budat, wrbtr TYPE wrbtr, END OF ty_fi_item. "1) Sorted no unica: varias partidas por sociedad/cuenta/ejercicio. DATA lt_fi_by_account TYPE SORTED TABLE OF ty_fi_item WITH NON-UNIQUE KEY bukrs hkont gjahr belnr buzei. "2) Sorted unica: clave tecnica de documento + posicion. DATA lt_fi_by_doc TYPE SORTED TABLE OF ty_fi_item WITH UNIQUE KEY bukrs belnr gjahr buzei. "3) Tipo publico de clase o interfaz. TYPES tt_fi_by_account TYPE SORTED TABLE OF ty_fi_item WITH NON-UNIQUE KEY bukrs hkont gjahr belnr buzei. "Insercion: el runtime ubica la posicion correcta. INSERT ls_item INTO TABLE lt_fi_by_account. IF sy-subrc <> 0. "Solo relevante si la tabla es UNIQUE y ya existe la clave. ENDIF. "Lectura exacta por clave unica. READ TABLE lt_fi_by_doc ASSIGNING FIELD-SYMBOL() WITH TABLE KEY bukrs = lv_bukrs belnr = lv_belnr gjahr = lv_gjahr buzei = lv_buzei. "Recorrido por prefijo de clave: bukrs + hkont + gjahr. LOOP AT lt_fi_by_account ASSIGNING FIELD-SYMBOL() WHERE bukrs = lv_bukrs AND hkont = lv_hkont AND gjahr = lv_gjahr. ENDLOOP. Tipo de clave SORTED Uso ideal Ventaja Riesgo UNIQUE KEY Documento unico, cache ordenada, clave tecnica. Evita duplicados y da resultado deterministico. Error si negocio permite duplicados reales.

END OF ty_price. DATA lt_price TYPE HASHED TABLE OF ty_price WITH UNIQUE KEY matnr vkorg vtweg valid_from. "3) Tipo reutilizable. TYPES tt_mat_by_matnr TYPE HASHED TABLE OF ty_material_attr WITH UNIQUE KEY matnr. "Poblar con INSERT INTO TABLE. INSERT VALUE #( matnr = 'MAT01' mtart = 'FERT' matkl = '001' meins = 'PC' ) INTO TABLE lt_mat_by_matnr. "Leer sin copia con table expression + ASSIGN. ASSIGN lt_mat_by_matnr[ matnr = lv_matnr ] TO FIELD-SYMBOL(). IF sy-subrc = 0. " apunta a la linea del hash. ENDIF. "Existencia: no copie la linea si solo necesita validar. IF line_exists( lt_mat_by_matnr[ matnr = lv_matnr ] ). ENDIF. "Borrado por clave completa. DELETE TABLE lt_mat_by_matnr WITH TABLE KEY matnr = lv_matnr. Necesidad HASHED adecuado? Explicacion Buscar material por MATNR exacto 500.000 veces Si La clave completa unica permite lookup promedio constante. Listar materiales por tipo MTART No como clave primaria Use SORTED por mtart o secondary sorted key. Mantener salida ALV en orden de fecha No como estructura principal HASHED no modela orden de negocio. Evitar duplicados por documento Si UNIQUE KEY protege la integridad de la cache. Buscar por rangos de fecha No Hash no aprovecha rangos; prefiera SORTED.

3.5.7 HASHED TABLE con secondary sorted y hashed keys

Tambien puede declarar claves secundarias en una HASHED TABLE. Esto es util cuando la ruta principal es lookup

exacto por ID, pero ocasionalmente se requiere recorrer por una clasificacion, fecha o clave alternativa.

TYPES: BEGIN OF ty_bp_cache, partner TYPE bu_partner, taxnum TYPE stcd1, country TYPE land1, name1 TYPE bu_name1tx, END OF ty_bp_cache. DATA lt_bp TYPE HASHED TABLE OF ty_bp_cache WITH UNIQUE KEY partner WITH UNIQUE HASHED KEY by_tax COMPONENTS taxnum country WITH NON-UNIQUE SORTED KEY by_country_name COMPONENTS country name1 partner. "Ruta primaria: Business Partner exacto. ASSIGN lt_bp[ partner = lv_partner ] TO FIELD-SYMBOL(). "Ruta alternativa unica: identificacion fiscal. ASSIGN lt_bp[ KEY by_tax COMPONENTS taxnum = lv_taxnum country = lv_country ] TO FIELD-SYMBOL(). "Ruta alternativa por rango/agrupacion: pais y nombre. LOOP AT lt_bp ASSIGNING FIELD-SYMBOL() USING KEY by_country_name

WHERE country = lv_country. ENDLOOP.

Use este patron con moderacion. Si el caso principal es reporte por pais/nombre y no lookup por partner, la estructura

principal deberia ser SORTED, no HASHED.

3.5.8 Como elegir la clave: completa, parcial, prefijo y alternativa

Patron de acceso real Clave recomendada Ejemplo Motivo Igualdad por todos los campos de clave y resultado unico HASHED UNIQUE primaria o secundaria matnr, partner, vbeln+posnr Maximiza lookup exacto. Igualdad por prefijo y multiples resultados SORTED NON-UNIQUE bukrs+hkont, kunnr+erdat Permite ubicar inicio y recorrer grupo. Rango por fecha dentro de entidad SORTED con entidad antes de fecha kunnr erdat vbeln El prefijo restringe y la fecha ordena. Consulta frecuente por dos rutas distintas Clave primaria + secondary key partner y taxnum+country Evita duplicar tablas y reduce escaneos. Solo se imprime/procesa todo STANDARD EMPTY KEY ALV, export, payload Menor overhead y mayor simplicidad. "Mal diseno de clave para rango: se consulta por cliente + fecha, "pero fecha quedo antes que cliente. El prefijo no ayuda. DATA lt_bad TYPE SORTED TABLE OF ty_sales_item WITH NON-UNIQUE KEY erdat kunnr vbeln posnr. LOOP AT lt_bad ASSIGNING FIELD-SYMBOL() WHERE kunnr = lv_kunnr AND erdat BETWEEN lv_from AND lv_to. ENDLOOP. "Mejor: cliente primero, fecha despues. DATA lt_good TYPE SORTED TABLE OF ty_sales_item WITH NON-UNIQUE KEY kunnr erdat vbeln posnr. LOOP AT lt_good ASSIGNING FIELD-SYMBOL() WHERE kunnr = lv_kunnr AND erdat BETWEEN lv_from AND lv_to. ENDLOOP.

3.5.9 Creacion dinamica, parametros y atributos de clase

En arquitectura ABAP, muchas tablas internas no viven solo como variables locales. Deben definirse como TYPES

publicos de clase, parametros de metodo, atributos cache o tablas retornadas. Mantenga la clave en el tipo para no perder

el contrato al pasar la tabla entre capas.

CLASS zcl_sales_cache DEFINITION PUBLIC FINAL CREATE PUBLIC. PUBLIC SECTION. TYPES: BEGIN OF ty_item, vbeln TYPE vbeln_va, posnr TYPE posnr_va, matnr TYPE matnr, kunnr TYPE kunnr, erdat TYPE erdat, END OF ty_item. TYPES tt_items TYPE STANDARD TABLE OF ty_item WITH EMPTY KEY WITH UNIQUE HASHED KEY by_doc_item COMPONENTS vbeln posnr WITH NON-UNIQUE SORTED KEY by_customer_date COMPONENTS kunnr erdat. METHODS constructor IMPORTING it_items TYPE tt_items. METHODS get_item IMPORTING iv_vbeln TYPE vbeln_va iv_posnr TYPE posnr_va RETURNING VALUE(rs_item) TYPE ty_item. PRIVATE SECTION.

Business Partner por partner y tax number HASHED primary + secondary hashed HASHED ... UNIQUE KEY partner WITH UNIQUE HASHED KEY by_tax COMPONENTS taxnum country Dos identificadores unicos. Stock por material-centro-almacen-lote SORTED NON-UNIQUE o HASHED segun consulta SORTED KEY matnr werks lgort charg Si se agrupa por material/centro, SORTED; si exacto, HASHED. "Caso: enriquecer posiciones de venta con datos de material. "Arquitectura recomendada: precargar una cache HASHED con proyeccion minima. TYPES: BEGIN OF ty_mat_cache, matnr TYPE matnr, mtart TYPE mtart, matkl TYPE matkl, END OF ty_mat_cache. DATA lt_mat_cache TYPE HASHED TABLE OF ty_mat_cache WITH UNIQUE KEY matnr. SELECT matnr, mtart, matkl FROM mara INTO TABLE @lt_mat_cache FOR ALL ENTRIES IN @lt_items WHERE matnr = @lt_items-matnr. LOOP AT lt_items ASSIGNING FIELD-SYMBOL(). ASSIGN lt_mat_cache[ matnr = -matnr ] TO FIELD-SYMBOL(). IF sy-subrc = 0. "Enriquecimiento sin SELECT SINGLE dentro del loop. ENDIF. ENDLOOP.

4. Complejidad y performance comparativa Operacion STANDARD SORTED HASHED Comentario tecnico READ por indice O(1) O(1) No aplica STANDARD/SORTED tienen indice primario; HASHED no tiene indice lineal. READ por clave primaria completa O(n) O(log n) O(1) promedio En STANDARD solo optimiza si se usa secondary key aplicable. READ por clave parcial/prefijo O(n) O(log n)+k si prefijo de clave No ideal HASHED requiere clave completa para beneficio real. LOOP AT WHERE sin key optimizable O(n) O(n) o mejor si WHERE usa clave O(n) o lookup si igualdad completa Depende de si el compilador puede transformar WHERE a acceso por clave. APPEND/INSERT masivo Muy eficiente Mas costoso por orden Costoso por hash/unicidad STANDARD gana para cargas secuenciales sin busquedas. DELETE por clave O(n) O(log n)+ajuste O(1) promedio En STANDARD se escanea; en SORTED/HASHED se usa indice/clave. Memoria Menor Media Mayor Las estructuras de indice/hash consumen memoria adicional. Secondary keys agregan overhead.

La complejidad no sustituye la medicion. En SAP, el costo real depende de ancho de linea, tipos profundos, Unicode,

garbage collection, modo de ejecucion, version del kernel, clave elegida, localidad de CPU cache y si existen copias

implicitas. Sin embargo, la complejidad es suficiente para detectar decisiones arquitectonicas peligrosas: un loop de

50.000 posiciones que hace READ lineal sobre 50.000 materiales puede ejecutar 2.500 millones de comparaciones

logicas.

4.1 Benchmarks simples comparativos

La siguiente tabla muestra un resultado cualitativo esperado para N lineas y M lecturas por clave. No son tiempos

universales; son una guia de tendencia. Ejecute el programa de microbenchmark en su sistema, con tipos de linea y

volumen reales.

Escenario STANDARD sin sort STANDARD + SORT + BINARY SEARCH

SORTED TABLE HASHED TABLE

100k lineas, 100k lookup exactos Peor: O(n*m) Bueno si se ordena una vez y no cambia Bueno: O(m log n) Mejor para clave completa unica: O(m) promedio 100k lineas, loop por rango de fechas Peor si WHERE lineal Medio: se puede ubicar inicio y avanzar Mejor si fecha es parte ordenada de la clave No recomendado Carga 100k y sin busquedas Mejor Coste extra de SORT innecesario Coste extra de orden Coste extra de hash Tabla cambia constantemente y se consulta por ID Malo por busquedas lineales Malo si hay que reordenar Bueno con costo de mantenimiento Bueno si clave unica exacta REPORT z_itab_benchmark_template. TYPES: BEGIN OF ty_line, id TYPE i, group TYPE i, text TYPE string, END OF ty_line. DATA lt_std TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY. DATA lt_sorted TYPE SORTED TABLE OF ty_line WITH UNIQUE KEY id. DATA lt_hash TYPE HASHED TABLE OF ty_line WITH UNIQUE KEY id. DATA lv_start TYPE i. DATA lv_end TYPE i. DATA lv_dummy TYPE string. CONSTANTS c_n TYPE i VALUE 100000. lt_std = VALUE #( FOR i = 1 UNTIL i > c_n ( id = i group = i MOD 100 text = |Item { i }| ) ). lt_sorted = CORRESPONDING #( lt_std ). lt_hash = CORRESPONDING #( lt_std ). GET RUN TIME FIELD lv_start. DO c_n TIMES. READ TABLE lt_std ASSIGNING FIELD-SYMBOL() WITH KEY id = sy-index. IF sy-subrc = 0. lv_dummy = -text. ENDIF. ENDDO. GET RUN TIME FIELD lv_end. WRITE: / 'STANDARD linear microseconds:', lv_end - lv_start. SORT lt_std BY id. GET RUN TIME FIELD lv_start. DO c_n TIMES. READ TABLE lt_std ASSIGNING WITH KEY id = sy-index BINARY SEARCH. IF sy-subrc = 0. lv_dummy = -text. ENDIF. ENDDO. GET RUN TIME FIELD lv_end. WRITE: / 'STANDARD binary microseconds:', lv_end - lv_start.

5.3 ASSIGNING vs INTO y FIELD-SYMBOLS

INTO copia la linea a una work area. ASSIGNING vincula un field-symbol a la linea de la tabla y evita la copia. Para lineas

anchas, tipos profundos, estructuras con strings, tablas anidadas o procesamiento masivo, ASSIGNING reduce memoria y

CPU. INTO es preferible cuando se requiere aislamiento, comparacion, buffering local o cuando modificar accidentalmente

la tabla seria peligroso.

Forma Ventajas Desventajas Escenario ideal Riesgo LOOP AT itab INTO wa Seguro, explicito, no modifica tabla salvo MODIFY. Copia por linea; costoso en estructuras grandes. Lineas pequenas, transformacion a otro destino. Copias invisibles en loops masivos. LOOP AT itab ASSIGNING

Sin copia de linea; permite modificar in-place. Alias directo; cambios son inmediatos. Actualizaciones masivas, lineas anchas. Modificar campos clave puede disparar mantenimiento de indices o errores. READ TABLE ... REFERENCE INTO dref Evita copia y permite semantica de referencia. Gestion de referencias y lifetime requiere cuidado. APIs internas orientadas a objetos. Retener referencias a lineas que luego cambian/se eliminan. "Costoso si ty_big_line tiene strings, tablas internas o muchos campos. LOOP AT lt_big INTO DATA(ls_big). ls_big-status = 'X'. MODIFY lt_big FROM ls_big. ENDLOOP. "Optimizado: sin copia ni MODIFY adicional. LOOP AT lt_big ASSIGNING FIELD-SYMBOL(). -status = 'X'. ENDLOOP. 5.4 Table expressions

Las table expressions permiten leer lineas en posiciones de expresion. Mejoran legibilidad, pero por defecto lanzan

CX_SY_ITAB_LINE_NOT_FOUND si no existe la linea, excepto en usos como ASSIGN, line_exists o line_index. Para

performance, deben especificar la clave cuando se necesita una secundaria o cuando la lectura no queda cubierta por la

clave primaria.

"Lectura moderna con manejo explicito de ausencia. TRY. DATA(ls_customer) = lt_customers[ kunnr = lv_kunnr ]. CATCH cx_sy_itab_line_not_found. "No existe. ENDTRY. "Uso recomendado para existencia sin excepcion. IF line_exists( lt_customers[ KEY by_kunnr COMPONENTS kunnr = lv_kunnr ] ). "Existe y se usa la clave by_kunnr. ENDIF. "Asignacion sin copia y sin excepcion no manejada. ASSIGN lt_customers[ KEY by_kunnr COMPONENTS kunnr = lv_kunnr ] TO FIELD-SYMBOL(). IF sy-subrc = 0. -status = 'A'. ENDIF. 5.5 LINE_EXISTS y LINE_INDEX

line_exists es la forma expresiva para verificar existencia. Evita TRANSPORTING NO FIELDS y no requiere manejar

excepcion. line_index devuelve el indice de una linea en un indice aplicable; SAP recomienda no usar line_index para

luego leer inmediatamente por indice si se puede leer directamente la linea o usar line_exists para existencia.

"Bueno: existencia por clave hash secundaria. IF line_exists( lt_sales[ KEY by_vbeln COMPONENTS vbeln = lv_vbeln ] ).

ENDIF.

"Evitar: doble acceso innecesario. DATA(idx) = line_index( lt_sales[ KEY by_customer_date COMPONENTS kunnr = lv_kunnr ] ). IF idx > 0. DATA(ls_sale) = lt_sales[ idx ]. "Segundo acceso: revisar necesidad real. ENDIF. 5.6 FILTER

FILTER crea una nueva tabla filtrada. Es expresivo y, cuando se usa con claves apropiadas, puede ser mas eficiente que

una comprehension generica con FOR. Debe usarse cuando realmente se necesita materializar una tabla resultado; si

solo se procesaran lineas, LOOP AT WHERE puede ahorrar memoria.

DATA lt_open_by_customer TYPE SORTED TABLE OF ty_item WITH NON-UNIQUE KEY kunnr status. DATA(lt_open) = FILTER #( lt_open_by_customer WHERE kunnr = lv_kunnr AND status = 'O' ). "Si no se requiere materializar lt_open, preferir LOOP para ahorrar memoria. LOOP AT lt_open_by_customer ASSIGNING FIELD-SYMBOL() WHERE kunnr = lv_kunnr AND status = 'O'. ENDLOOP. 5.7 REDUCE, FOR y VALUE

REDUCE y FOR permiten expresar agregaciones y construcciones de tablas de forma declarativa. Son excelentes para

transformaciones acotadas y legibles. En rutas criticas, valide memoria: VALUE y FOR suelen materializar resultados;

REDUCE evita algunas work areas pero no elimina el costo de iterar. Use BASE para agregar sin perder contenido previo

y evite constructor expressions gigantes que creen copias intermedias.

"Agregacion moderna: total por filtro simple. DATA(lv_total) = REDUCE wrbtr( INIT sum = CONV wrbtr( 0 ) FOR item IN lt_items WHERE ( bukrs = lv_bukrs ) NEXT sum = sum + item-amount ). "Construccion de tabla destino. DATA lt_summary TYPE STANDARD TABLE OF ty_summary WITH EMPTY KEY. lt_summary = VALUE #( FOR item IN lt_items WHERE ( status = 'O' ) ( bukrs = item-bukrs belnr = item-belnr amount = item-amount ) ).

6. Cuándo usar BINARY SEARCH, SORTED, HASHED y claves secundarias Decision Usar cuando Evitar cuando Ventajas Riesgos BINARY SEARCH STANDARD ya esta ordenada una vez y se hacen muchas lecturas; no se modifica entre sort y reads. La tabla cambia entre lecturas; el orden no coincide exactamente con la clave; hay riesgo de mantenimiento. Mejora lectura a O(log n) sin cambiar tipo. Errores silenciosos si no se ordena por los mismos campos y direccion. Evitar STANDARD Hay READ/LOOP WHERE repetidos por clave y volumen alto. Carga simple y loop completo. Reduce complejidad algoritmica. Sobredisenar HASHED/SORTED para tablas pequenas. Preferir HASHED Lookup exacto, clave unica, no hay rangos ni indice. Necesita orden, acceso por indice o duplicados. Lectura promedio constante. Mayor memoria; clave debe ser estable. Preferir SORTED Rangos, prefijos, orden natural, procesamiento secuencial por clave. Solo lookup exacto unico y sin orden. Buena para LOOP WHERE y rangos. Insercion mas costosa. Claves secundarias Misma tabla requiere varios patrones de acceso y volumen justifica overhead. Tabla pequena o accesos raros. Evita duplicar tablas cache. Memoria y costo de mantenimiento de indices.

AND hkont = -hkont AND gjahr = p_gjahr. "Procesa solo el rango relevante. ENDLOOP. ENDLOOP. 7.3 Integracion: deduplicacion de mensajes entrantes

Problema: una interfaz recibe eventos con idempotency_key. Debe procesar cada evento una sola vez. Solucion:

HASHED TABLE WITH UNIQUE KEY idempotency_key para detectar duplicados en memoria antes de persistir o llamar

APIs externas.

DATA lt_seen TYPE HASHED TABLE OF ty_event_key WITH UNIQUE KEY idempotency_key. LOOP AT lt_events ASSIGNING FIELD-SYMBOL(). INSERT VALUE #( idempotency_key = -idempotency_key ) INTO TABLE lt_seen. IF sy-subrc <> 0. CONTINUE. "Duplicado en el paquete. ENDIF. "Procesar evento. ENDLOOP.

8. Anti-patrones comunes y version optimizada Anti-patron Por que es caro Version optimizada Impacto esperado READ lineal dentro de LOOP grande Complejidad O(n*m). HASHED/SORTED o secondary key. Reduccion drastica de CPU. LOOP AT WHERE sobre STANDARD sin key Evalua todas las lineas. USING KEY con secondary sorted o cambiar a SORTED. Menos comparaciones y mejor cache locality. INTO para lineas anchas y luego MODIFY Copia + busqueda/modificacion. ASSIGNING y modificar in-place. Menos memoria temporal y CPU. DEFAULT KEY implicito Clave inesperada y dependiente de tipos de campo. WITH EMPTY KEY o clave explicita. Menos bugs y contratos mas claros. Table expression sin manejo de ausencia Excepcion no controlada. line_exists, ASSIGN, OPTIONAL/DEFAULT o TRY/CATCH. Robustez sin sacrificar claridad. Multiples tablas duplicadas para indices alternativos Memoria duplicada y sincronizacion manual. Secondary keys en una tabla. Menos riesgo de inconsistencia. "Incorrecto: loop anidado por busqueda lineal. LOOP AT lt_vbap ASSIGNING FIELD-SYMBOL(). READ TABLE lt_makt INTO DATA(ls_makt) WITH KEY matnr = -matnr spras = sy-langu. IF sy-subrc = 0. -maktx = ls_makt-maktx. ENDIF. ENDLOOP. "Optimizado: clave hash unica por material/idioma. DATA lt_makt_h TYPE HASHED TABLE OF ty_makt WITH UNIQUE KEY matnr spras. lt_makt_h = CORRESPONDING #( lt_makt ). LOOP AT lt_vbap ASSIGNING . ASSIGN lt_makt_h[ matnr = -matnr spras = sy-langu ] TO FIELD-SYMBOL(). IF sy-subrc = 0. -maktx = -maktx. ENDIF. ENDLOOP.

9. Performance tuning y memoria en tablas internas 9.1 Costos ocultos de copias innecesarias

Las copias se producen al usar INTO, asignaciones completas entre tablas, VALUE/FOR que materializan resultados,

CORRESPONDING sobre datasets grandes, parametros por valor y conversiones de tipos profundos. ABAP tiene

optimizaciones internas, pero un arquitecto no debe depender de ellas para rutas criticas. En lineas anchas, una copia

puede costar mas que la comparacion de clave.

 Use ASSIGNING o REFERENCE INTO cuando no necesite una copia aislada.

 Evite construir tablas intermedias si un LOOP AT WHERE procesa el resultado una sola vez.

 Prefiera TRANSPORTING NO FIELDS o line_exists para existencia.

 Evite pasar tablas grandes por valor a metodos; use IMPORTING por referencia semantica o CHANGING segun el

contrato.

 Reduzca el ancho de linea: seleccione solo columnas necesarias y use tipos minimos para caches.

9.2 INTO CORRESPONDING

INTO CORRESPONDING es seguro frente al orden de columnas y mejora mantenibilidad, especialmente en SELECT con

estructuras no identicas. Su costo depende de mapeo de nombres, cantidad de columnas y volumen. En SQL moderno,

seleccionar campos explicitos y mapear a una estructura destino adecuada suele ser preferible a SELECT * seguido de

copias. El problema no es INTO CORRESPONDING en si; el problema es usarlo para mover estructuras gigantes con

campos innecesarios en loops masivos.

"Evitar: trae y copia demasiados campos. SELECT * FROM vbak INTO CORRESPONDING FIELDS OF TABLE @lt_big_vbak. "Preferir: proyeccion minima y tipo destino dedicado. SELECT vbeln, kunnr, erdat, netwr FROM vbak INTO TABLE @DATA(lt_sales_min) WHERE erdat BETWEEN @p_from AND @p_to. 9.3 Copiar referencias vs copiar datos

Copiar una referencia copia el puntero al objeto o dato referenciado; copiar datos duplica el contenido logico. En ABAP

OO, tablas de referencias pueden reducir memoria cuando varias estructuras apuntan al mismo objeto, pero introducen

aliasing: modificar el objeto por una referencia afecta a todos los consumidores. En tablas internas de datos planos,

ASSIGNING evita copia temporal sin convertir el modelo en referencias persistentes.

Tecnica Memoria CPU Riesgo Uso recomendado INTO DATA(ls) Copia linea Mayor en lineas anchas Datos aislados, pero copia costosa Cuando se requiere snapshot local. ASSIGNING Sin copia de linea Menor Modificacion accidental in- place Loops masivos y actualizaciones. REFERENCE INTO dref Referencia a linea Menor copia Lifetime/aliasing; cuidado con DELETE/MODIFY APIs internas y lectura diferida controlada. Tabla de REF TO object Comparte objetos Depende de dereferenciacion Estado compartido dificil de razonar Modelos OO, caches de instancias. 9.4 Uso eficiente de memoria

 Declare claves secundarias solo si el volumen y la frecuencia de lectura lo justifican.

 Libere tablas grandes con FREE cuando el bloque de procesamiento termina y la memoria debe devolverse.

 Use CLEAR para reutilizar una tabla cuando se conservara el bloque de memoria para recargas similares; use FREE

para liberar.

 Evite tablas internas anidadas dentro de lineas masivas salvo que el modelo lo requiera.

 Evite SELECT * para caches; el ancho de linea afecta cada copia, comparacion, hash e indice.

 Considere paquetes/chunks en jobs para no retener millones de lineas innecesariamente.