воскресенье, 8 ноября 2015 г.

Оптимизация запроса ABAP

[ABAP] Учимся правильно использовать FOR ALL ENTRIES IN

По мотивам статьи...

Да, сам видел в ST04N как данные куба считываются по кусочкам (по 5 значений).

Количество значений передаваемых в оператор IN регулируется настроченным параметром SAP - max_in_blocking_factor

Но чем больше параметр, тем больше нужно памяти для хранения результата.

Хинты для "локального" преодоления параметра
%_hints db2 '&max_in_blocking_factor 500&' или 
%_hints oracle '&max_in_blocking_factor 500&'

Пример:
select * from (table) appending corresponding fields of table lt_table for all entries in lt_tmp where x = lt_tmp-x
%_hints db2 '&max_in_blocking_factor 500&'.

Альтернатива - RANGE 
Вместо for all entries использовать range, но есть ньюансы:
- Если range будет содержать более 2000 строк, то он выйдет за размер SQL запроса передаваемого в базе. Результат - DBIF_RSQL_INVALID_RSQL
- т.о. возникает потребность следить за range

1 комментарий:

Sergey Kostuchenko комментирует...

А если более одного условия в WHERE? Может лучше собирать селект, динамически формирую условие?

case ls_tvarvc_row-opti.
when 'BT'.
lv_where = ` BETWEEN '` && ls_tvarvc_row-low
&& `' AND '` && ls_tvarvc_row-high && `'`.
when 'EQ'.
lv_where = ` GE '` && ls_tvarvc_row-low && `'`.
when others.
lv_where = ` ` && ls_tvarvc_row-opti && ` '`
&& ls_tvarvc_row-low && `'`.
endcase.

lv_where = `/BIC/ZBLDAT` && lv_where.

if ls_tvarvc_row-sign = 'E'.
lv_where = ` NOT (` && lv_where && ` )`.
endif.

select /BIC/ZBELNR
from /BIC/AZMM_D0900
into table gt_filter_invoices
where (lv_where).