- Selecione Ctrl + Shift + N para criar um novo objeto do repositório ABAP.
- Digite a palavra banco de dados no campo de filtro, marque o resultado da pesquisa Tabela de banco de dados e selecione Continuar.
- Atribua o novo objeto ao pacote com o qual você está trabalhando e insira o nome ZS4D401_FLIGHTS. Insira uma descrição para a tabela e selecione Seguinte.
- Atribua o objeto a uma ordem de transporte e selecione Concluir.
- Insira o seguinte código entre chaves: Code Snippet1234567891011key client : abap.clnt not null; key carrier_id : /dmo/carrier_id not null; key connection_id : /dmo/connection_id not null; key flight_date : /dmo/flight_date not null; @Semantics.amount.currencyCode : 'zs4d401_flights.currency_code' price : /dmo/flight_price; currency_code : /dmo/currency_code; plane_type_id : /dmo/plane_type_id; seats_max : /dmo/plane_seats_max; seats_occupied : /dmo/plane_seats_occupied;
- Selecione Ctrl + F3 para ativar a tabela.
- Crie uma nova classe ABAP chamada ZCL_FILL_ZS4D401_FLIGHTS.
- Insira o seguinte código na implementação do método main: Code Snippet123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566DATA flights TYPE TABLE OF /dmo/flight. DATA insert_tab TYPE TABLE OF /dmo/flight. DELETE FROM ZS4D401_flights. SELECT FROM /dmo/flight FIELDS * ORDER BY carrier_Id, connection_id INTO TABLE @flights . LOOP AT flights INTO DATA(first_date). * Original table flights has 2 flights per connection. Only process the first IF sy-tabix MOD 2 = 0. CONTINUE. ENDIF. *Extend flight dates by 2000 days DO 2000 TIMES. APPEND first_date TO insert_tab. first_date-flight_date += 1. ENDDO. * ENDIF. ENDLOOP. * Read highest connection number for each flight SELECT FROM /dmo/flight AS main FIELDS carrier_Id, connection_id, flight_date, price, currency_code, plane_type_id WHERE connection_id = ( SELECT MAX( connection_id ) FROM /dmo/flight WHERE carrier_id = main~carrier_id ) AND flight_Date = ( SELECT MIN( flight_date ) FROM /dmo/flight WHERE carrier_id = main~carrier_id AND connection_id = main~connection_id ) GROUP BY carrier_id, connection_Id, flight_date, price, currency_code, plane_type_id ORDER BY carrier_id, connection_id INTO TABLE @DATA(max). *Add 50 new connection numbers and 2000 days of flights for each LOOP AT max INTO DATA(line). DO 50 TIMES. line-connection_id += 1. line-plane_type_id = SWITCH #( CONV i( line-connection_id ) MOD 2 WHEN 0 THEN 'A330' WHEN 1 THEN 'A350' ). first_date = CORRESPONDING #( line ). DATA(repetitions) = COND i( WHEN line-carrier_id = 'LH' AND line-connection_id = '0405' THEN 4000 ELSE 2000 ). DO repetitions TIMES. first_date-seats_max = 220. APPEND first_date TO insert_tab. first_date-flight_date += 1. ENDDO. ENDDO. ENDLOOP. SORT insert_tab BY carrier_Id connection_id flight_date. DELETE ADJACENT DUPLICATES FROM insert_tab COMPARING carrier_id connection_id flight_date. INSERT ZS4D401_flights FROM TABLE @insert_tab. out->write( |Generated { sy-dbcnt } rows in table ZS4D401_flights| ).
- Selecione Ctrl + F3 para ativar a classe.
- Selecione F9 para executar a classe. O método main preenche uma tabela de banco de dados adicional que é necessária para os snippets de código nas duas seções seguintes.
Trabalhar com tabelas ordenadas e hash
Objective
Experimente: preparação de exemplo de código
Tabelas ordenadas e hash
Até agora, trabalhamos com tabelas internas padrão. Os dados em uma tabela padrão não são mantidos em uma determinada sequência de ordenação. Consequentemente, quando você lê dados da tabela, o sistema deve procurar a tabela sequencialmente até encontrar a linha ou linhas necessárias. Dependendo do tamanho da tabela, isso pode demorar algum tempo.
Você pode otimizar a performance de acessos de leitura a tabelas internas usando tabelas ordenadas ou hash.

Em uma tabela ordenada, o conteúdo da tabela é sempre ordenado de acordo com os campos-chave em ordem crescente. Quando você insere um novo registro na tabela, o sistema garante que ele seja colocado na posição correta. Como os dados são sempre ordenados, o sistema pode recuperar registros de forma mais eficiente do que a partir de uma tabela padrão (desde que você siga determinadas regras).
As tabelas hash são gerenciadas usando um algoritmo hash especial. Isso garante que o sistema possa recuperar registros muito rapidamente, mesmo se a tabela for extremamente grande. No entanto, esse ganho de performance só funciona em casos muito específicos.
Acesso a uma tabela ordenada
Neste vídeo, você verá como acessar uma tabela ordenada.

Quando você declara uma tabela hash, deve defini-la com uma chave única – nunca são permitidas duplicatas.
Assista ao vídeo para saber como acessar uma tabela hash.
Quando utilizar tabelas padrão, ordenadas e hash

Se você preencher uma tabela interna e, subsequentemente, implementar um loop sobre toda a tabela, pode usar uma tabela padrão. A otimização da performance de tabelas ordenadas e hash é irrelevante, uma vez que não existe nenhum filtro no loop.

Este exemplo mostra quando você deve usar tabelas ordenadas e hash. Ele contém um loop sobre as conexões de tabela usando o primeiro campo-chave na cláusula where. Este é um caso para a utilização de uma tabela ordenada, uma vez que o sistema pode utilizar a técnica de pesquisa binária mesmo que a chave não esteja completamente indicada.
Dentro do loop, o programa procura entradas na tabela companhias aéreas. Por isso, existem acessos repetidos à tabela usando a chave completa. Este é um caso ideal para usar uma tabela hash.
Tempos de execução comparativos de tabelas padrão, ordenadas e hash
Esta figura compara os tempos de execução de tabelas padrão, ordenadas e hash.

Preenchimento de tabelas ordenadas e hash
Quando você usa uma tabela padrão, pode usar a instrução APPEND para adicionar o conteúdo de uma área de trabalho ao final da tabela. Isso não é possível com tabelas hash e leva a um erro de sintaxe.
Tecnicamente, você pode utilizar a instrução APPEND para preencher uma tabela ordenada. No entanto, você corre o risco de causar um erro em tempo de execução se a linha que você tenta anexar não pertencer ao final da tabela de acordo com a sequência de ordenação. Isso aconteceria em nosso exemplo.

A maneira de preencher uma tabela hash e preencher uma tabela ordenada com segurança é usar a instrução INSERT. INSERT garante que a nova linha seja inserida na posição correta na tabela.
Experimente: tabelas ordenadas e hash
- Crie uma nova classe que implemente a interface IF_OO_ADT_CLASSRUN.
- Copie o seguinte snippet de código para a parte de implementação do método if_oo_adt_classrun~main( ):Code Snippet1234567891011* Run this class using the ABAP Profiler to measure relative access times for standard, sorted, and hashed tables data(flights) = new lcl_flights( ). flights->access_standard( ). flights->access_sorted( ). flights->access_hashed( ). out->write( |Done| ).
- Mude para a guia Tipos locais e copie o seguinte snippet de código para o editor: Code Snippet1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465CLASS lcl_flights DEFINITION. PUBLIC SECTION. METHODS constructor. METHODS access_standard. METHODS access_sorted. METHODS access_hashed. PRIVATE SECTION. DATA standard_table TYPE STANDARD TABLE OF zs4d401_flights WITH NON-UNIQUE KEY carrier_id connection_id flight_date. DATA sorted_table TYPE SORTED TABLE OF zs4d401_flights WITH NON-UNIQUE KEY carrier_id connection_id flight_date. DATA hashed_table TYPE HASHED TABLE OF zs4d401_flights WITH UNIQUE KEY carrier_id connection_id flight_date. DATA key_carrier_id TYPE /dmo/carrier_id. DATA key_connection_id TYPE /dmo/connection_id. DATA key_date TYPE /dmo/flight_date. METHODS set_line_to_read. ENDCLASS. CLASS lcl_flights IMPLEMENTATION. METHOD access_hashed. DATA(result) = hashed_table[ carrier_Id = me->key_carrier_id connection_Id = me->key_connection_id flight_date = me->key_date ]. ENDMETHOD. METHOD access_sorted. DATA(result) = sorted_table[ carrier_Id = me->key_carrier_id connection_Id = me->key_connection_id flight_date = me->key_date ]. ENDMETHOD. METHOD constructor. SELECT FROM zs4d401_flights FIELDS * INTO TABLE @standard_table. SELECT FROM zs4d401_flights FIELDS * INTO TABLE @sorted_table. SELECT FROM zs4d401_flights FIELDS * INTO TABLE @hashed_table. set_line_to_read( ). ENDMETHOD. METHOD access_standard. DATA(result) = standard_table[ carrier_Id = me->key_carrier_id connection_Id = me->key_connection_id flight_date = me->key_date ]. ENDMETHOD. METHOD set_line_to_read. DATA(line) = standard_table[ CONV i( lines( standard_table ) * '0.65' ) ]. me->key_carrier_id = line-carrier_Id. me->key_connection_Id = line-connection_id. me->key_date = line-flight_date. ENDMETHOD. ENDCLASS.
- Selecione Ctrl + F3 para ativar a classe.
- Clique com o botão direito do mouse no Editor e selecione Perfil como...→Aplicação ABAP (console).
- Em Detalhes, desmarque o campo de seleção Acesso ao banco de dados SQL e selecione Concluir.
- Mude para a perspectiva Profiler ABAP e clique duas vezes no item de rastreamento (talvez seja necessário atualizar a exibição primeiro).
- Selecione Lista de ocorrências.
- Compare os tempos de execução dos métodos access_standard( ), access_sorted( ) e access_hashed( ).
Trabalhar com tabelas ordenadas e hash
Você percebe que seu código contém grandes tabelas internas do tipo Tabela padrão. Você analisa a forma como essas tabelas são acessadas no código e descobre que elas só são acessadas por chave. Para melhorar a performance, você modifica a definição das tabelas internas para Tabela ordenada ou Tabela hash, dependendo da forma como são acessadas.
Modelo:
- /LRN/CL_S4D401_ITS_FSYM (classe global)
Solução:
- /LRN/CL_S4D401_ITS_TABLE_KIND (classe global)