Параллельный курсор (Parallel Cursor) в ABAP
Одна из основных задач ABAP разработчика заключается в оптимизации уже ранее написанного кода. Как правило, потенциально «опасных» конструкций не так и много, сюда можно отнести типы таблиц (стандартные, сортированные, хешированные), нюансы конструкции «select endselect» и, конечно, вложенные циклы!
Создадим программу, в которой прочитаем таблицу со списком аэропортов SAIRPORT и таблицу со списком полетов SFLIGHTS. Затем для каждого аэропорта найдем соответствующие полёты и выведем информацию о полётах на экран.
REPORT z_parallel_cursor.
DATA: lt_airports TYPE STANDARD TABLE OF s_airport,
lt_flights TYPE STANDARD TABLE OF sflights.
SELECT id FROM sairport INTO TABLE lt_airports.
SELECT * FROM sflights INTO TABLE lt_flights.
LOOP AT lt_airports ASSIGNING FIELD-SYMBOL(<fs_airport>).
LOOP AT lt_flights ASSIGNING FIELD-SYMBOL(<fs_flight>) WHERE airpfrom = <fs_airport>.
WRITE:/ <fs_flight>-airpfrom, <fs_flight>-cityfrom, <fs_flight>-cityto.
ENDLOOP.
ENDLOOP.
В данном примере встречается потенциально не эффективная конструкция — вложенные циклы (Nested Loops). При больших количествах строк во внутренних таблицах данная конструкция может выполнятся существенное время.
Перепишем программу, использовав концепцию параллельного курсора (Parallel Cursor):
REPORT z_parallel_cursor.
DATA: lt_airports TYPE STANDARD TABLE OF s_airport,
lt_flights TYPE STANDARD TABLE OF sflights,
lv_index TYPE sy-tabix.
SELECT id FROM sairport INTO TABLE lt_airports.
SELECT * FROM sflights INTO TABLE lt_flights.
SORT lt_airports.
SORT lt_flights BY airpfrom.
LOOP AT lt_airports ASSIGNING FIELD-SYMBOL(<fs_airport>).
READ TABLE lt_flights TRANSPORTING NO FIELDS WITH KEY airpfrom = <fs_airport> BINARY SEARCH.
IF sy-subrc IS INITIAL.
lv_index = sy-tabix.
LOOP AT lt_flights ASSIGNING FIELD-SYMBOL(<fs_flight>) FROM lv_index.
IF <fs_flight>-airpfrom NE <fs_airport> .
EXIT.
ENDIF.
WRITE:/ <fs_flight>-airpfrom, <fs_flight>-cityfrom, <fs_flight>-cityto.
ENDLOOP.
ENDIF.
ENDLOOP.
Какие изменения мы сделали:
- Сделали сортировку таблиц для выполнения двоичного (бинарного) поиска значения.
- Первый цикл оставляем неизменным.
- В самом начале цикла методом двоичного поиска ищем первый элемент с искомым ключом.
- Если такой элемент находим, то запоминаем его положение (sy-tabix) в таблице.
- Второй цикл мы начинаем с индекса первой найденной записи.
- Так как таблица у нас сортирована по искомому ключу, то все элементы с данным ключом будут идти один за другим.
- В цикле мы проверяем соответствие ключа искомому значению. Если записи с таким ключом закончились, то выходим из второго цикла.
Получается, что мы не перебираем каждый элемент внутреннего цикла на соответствие условию, а вычленяем среди всех строк только строки, которые удовлетворяют нашему поиску, отбрасывая строки, которые будут следовать после искомых.