Который имеет лучшую производительность: SELECT ... ENDSELECT (1 на 1) или SELECT ... INTO TABLE / LOOP AT - PullRequest
2 голосов
/ 01 апреля 2019

Мне нужно прочитать 10.000.000 записей из таблицы.

Это лучше:

  • для чтения этих записей одна за другой, используя SELECT ... ENDSELECT (без внутренней таблицы)
  • или прочитать все из них одновременно, используя SELECT ... INTO TABLE itab, а затем LOOP через эту внутреннюю таблицу?

Ответы [ 2 ]

5 голосов
/ 01 апреля 2019

Если все 10 000 000 записей помещаются в основную память ABAP, вы должны выбрать все из них одним SELECT ... INTO TABLE ..., за которым следует LOOP.

Это сводит к минимуму дорогостоящее взаимодействие с базой данных и будет самым быстрым.

Если записи не помещаются в основную память, вам необходимо извлечь их в пакетах. Проверьте PACKAGE SIZE дополнение оператора SELECT.

2 голосов
/ 02 апреля 2019

Они имеют примерно одинаковую скорость

Вопреки распространенному мнению, SELECT ... ENDSELECT не выбирает строки один за другим, поэтому его производительность не намного хуже, чем SELECT ... INTO TABLE.См. Объяснение здесь .

Большая проблема с SELECT ... ENDSELECT в том, что она предотвращает другие улучшения производительности

Рассмотрим эту кодировку:

SELECT matnr FROM mara  
    INTO ls_mara WHERE (...).
  SELECT SINGLE ebeln
      FROM ekpo 
      INTO ls_ekpo 
      WHERE matnr = ls_mara-matnr.
  ...
ENDSELECT.

Большую часть времени будет проводиться с SELECT SINGLE на таблице ekpo, и для решения этой проблемы используется FOR ALL ENTRIES, однако для этого вам нужна внутренняя таблица.
Поэтому ее необходимо преобразоватьв SELECT ... INTO TABLE в любом случае:

SELECT matnr FROM mara 
    INTO TABLE lt_mara WHERE (...).
IF lt_mara IS NOT INITIAL.
  SELECT matnr, ebeln FROM ekpo
      INTO TABLE @lt_ekpo        "make it SORTED by matnr"
      FOR ALL ENTRIES IN @lt_mara
      WHERE matnr = @lt_mara.
ENDIF. 
LOOP AT lt_mara ASSIGNING <fs_mara>.
  READ TABLE lt_ekpo ASSIGNING <fs_ekpo>
      WITH KEY matnr = <fs_mara>-matnr.
  ...
ENDLOOP.

Вы должны избегать SELECT ... ENDSELECT, не из-за своей собственной производительности, но чтобы упростить другие улучшения.

...