SORTED em vez de STANDARD nas tabelas de cache

images/thumbnail.jpg - Thumbnail

Há bastante tempo atrás escrevi aqui um artigo demonstrando as vantagens de usar tabelas internas com índices definidos em vez de simples tabelas STANDARD.

Confissão: é tal o hábito instalado que desde então, quase todas as tabelas internas que criei continuaram a ser STANDARD TABLE.

É muito frequente criar tabelas internas para fazer cache de dados que sei que vou utilizar amiúde dentro de LOOPs para evitar fazer SELECT SINGLEs lá pelo meio.

Análises parciais na SE30

images/thumbnail.jpg - Thumbnail

Claro que já conheces a transacção SE30 (Análise de tempo de execução) e claro que a usas amiúde para analisar programas standard e descobrir nele tabelas, funções, BADIs e quejandos.

Ora se fores como eu, manténs uma relação de amor-ódio com esta transacção: se por um lado a amas por graças a ela consegues ver as entranhas de um programa sem ter de fazer debug, por outro lado odeia-la porque normalmente a lista de entranhas costuma ter milhares de linhas e tornar-se ingerível.

LOOP ASSIGNING em vez de LOOP INTO

images/thumbnail.jpg - Thumbnail

No princípio era o INTO. Aliás, no princípio nem sequer era o INTO.

Soneca

images/thumbnail.jpg - Thumbnail

Volta não volta é preciso meter um programa a dormir. E como em quase tudo, há várias formas de o fazer, e umas formas são melhores do que outras.

A forma mais standard de conseguir isto em ABAP é a seguinte:

WAIT UP TO 10 SECONDS.

A vantagem do WAIT UP TO N SECONDS é que o processo é libertado durante estes 10 segundos, ficando assim disponível para quem o quiser apanhar. A grande desvantagem é que faz um COMMIT implícito, o que nem sempre é bom. Se não te importares com o COMMIT, esta é a melhor forma de adormeceres o teu programa. Nota que não dá para o adormecer por 1.5 segundos pois o parâmetro só aceita números inteiros.

Partida... lagarta... fugida!

images/thumbnail.jpg - Thumbnail

Senhoras e senhores, meninos e meninas, a corrida está prestes a começar.

Introdução

Apresento-vos as 4 participantes. São 4 tabelas internas, de diferentes raças e credos, que se vão pelejar pelo título atlético do LOOP em velocidade. Aqui estão elas:

Concorrente 1: DATA: LT_ITEM TYPE TABLE Concorrente 2: DATA: LT_ITEM_HASHED TYPE HASHED TABLE Concorrente 3: DATA: LT_ITEM_SORTED TYPE SORTED TABLE Concorrente 4: DATA: LT_ITEM TYPE TABLE + INTO INDEX

LOOP FROM INDEX

images/thumbnail.jpg - Thumbnail

É muito fácil meter os pés pelas mãos no que toca a performance quando se manipula tabelas internas. Principalmente quando elas são assim a tender para o grandalhonas. É até comum que estes problemas só surjam passados uns meses, quando as tabelas tendem a crescer com o tempo.

Por exemplo, quando fazes loop a duas tabelas, uma de cabeçalhos e outra de itens, fazes assim?

LOOP AT itab1 ASSIGNING <fs1>.
   LOOP AT itab2 ASSGNING <fs2> WHERE field1 = <fs1>-field1.
   ENDLOOP.
ENDLOOP.

Sabias que, para tabelas grandes, isto pode demorar séculos porque o LOOP WHERE corresponde a fazer uma leitura sequencial da itab2 para cada entrada da itab1?

SAT - A nova ferramenta de análise de execução

images/thumbnail.jpg - Thumbnail

Desde pequenino que uso a transacção SE30 para duas coisas diferentes:

  • Analisar um programa que desconheço (normalmente standard) para saber que funções usa, que BADIs disponibiliza, etc;

  • Analisar um programa meu em busca de problemas de performance.

A verdade, nua e crua, é que a transacção SE30 é uma porcaria pegada. Extremamente limitada e inflexível, não dá jeito nenhum para qualquer análise mais complexa.

Aparentemente os senhores da SAP concordam e resolveram substitui-la pela fantástica nova ferramenta SAT - ABAP Runtime Analysis , em tudo mais sofisticada. Pode ser acedida, como seria de esperar, através da transacção SAT.

Macros - Velocidade de ponta

Normalmente quando há um pedaço de código que pretendemos reutilizar várias vezes, transformamo-lo numa sub-rotina que pode depois ser invocada repetidamente. Embora a SAP não saiba estruturar o seu próprio código, ainda assim, o ABAP, coitadinho, permite-o. E até disponibiliza várias alternativas para modularizar o código. Eu conto quatro alternativas que listo aqui, da mais rígida para a mais flácida: METHOD, FUNCTION, FORM, DEFINE. Se os 3 primeiros são já familiar de todos, o último - DEFINE - quase ninguém usa. O DEFINE permite definir macros em ABAP. E o que são macros? São sub-rotinas aparentes.

Aparentes porquê?

READ TABLE blablabla TRANSPORTING NO FIELDS

Por vezes ao fazer READ TABLE a uma tabela interna queremos apenas verificar se um determinado registo existe, e não nos preocupamos com os dados retornados. Algo tipo:

READ TABLE lt_kna1 INTO wa_kna1 WITH KEY kunnr = l_kunnr.
CHECK SY-SUBRC = 0.

Ora já que a estrutura WA_KNA1 não vai ser necessária de qualquer forma, mais vale não a usar, usando antes a opção TRANSPORTING NO FIELDS:

READ TABLE lt_kna1 TRANSPORTING NO FIELDS WITH KEY kunnr = l_kunnr.
CHECK SY-SUBRC = 0.

O Abapinho saúda-vos.