К основному контенту

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

В этой статье я решил написать пример, как не нужно писать SQL запросы в ABAP. Для примера взял кусок кода с SQL запросом из реальной Z программы и на его основе поставил эксперимент.
Итак, есть вот такой SQL:
SELECT  *
        INTO    ls_mseg
        FROM    mseg AS m
        .
 
    SELECT  SINGLE mblnr
    INTO    ls_mseg-mblnr
    FROM    mseg
    WHERE   smbln = ls_mseg-mblnr
      AND   sjahr = ls_mseg-mjahr
      AND   smblp = ls_mseg-zeile.
    CHECK sy-subrc <> 0.
 
* ToDo
 
  ENDSELECT.
По сути, этот алгоритм отсеивает документы сторно. Я намеренно убрал все условия WHERE из первого оператора SELECT для наглядности.
Итак, делаем пример с замерами:
GET RUN TIME FIELD t1.
 
  SELECT  *
        INTO    ls_mseg
        FROM    mseg AS m
        .
 
    SELECT  SINGLE mblnr
    INTO    ls_mseg-mblnr
    FROM    mseg
    WHERE   smbln = ls_mseg-mblnr
      AND   sjahr = ls_mseg-mjahr
      AND   smblp = ls_mseg-zeile.
    CHECK sy-subrc <> 0.
 
    CNT = CNT + 1.
  ENDSELECT.
 
  GET RUN TIME FIELD t2.
 
  t2 = t2 - t1.
 
  WRITE: / 'EXECUTION TIME:', t2.
  WRITE: / 'RECORDS COUNT:', CNT.
Что бы не быть голословным, я посчитал время выполнения всего этого куска и количество записей, которое он вернул:
EXECUTION TIME:  2.545.691
RECORDS COUNT:       9.093
Итак, условно у нас 9 тысяч записей за 2.5 млн микросекунд.

Конечно, ерунда, но! Давайте воспользуемся средствами ABAP и откажемся от вложенного SQL запроса. Меняем код:
GET RUN TIME FIELD t1.
 
  SELECT  *
        INTO    ls_mseg
        FROM    mseg AS m
        WHERE
    NOT EXISTS (
    SELECT  *
    FROM    mseg
    WHERE   smbln = m~mblnr
      AND   sjahr = m~mjahr
      AND   smblp = m~zeile
    )
        .
    CNT = CNT + 1.
  ENDSELECT.
 
  GET RUN TIME FIELD t2.
 
  t2 = t2 - t1.
 
  WRITE: / 'EXECUTION TIME:', t2.
  WRITE: / 'RECORDS COUNT:', CNT.
И снова для наглядности приведем цифры:
EXECUTION TIME:    440.612
RECORDS COUNT:       9.093
В итоге получаем те же строчки, но за какое время?
Очень надеюсь, что данная статья кому-то будет полезна при составлении SQL запросов для известных алгоритмов

Полный код программы
REPORT  zztest.
 
START-OF-SELECTION.
 
  DATA: ls_mseg TYPE mseg.
 
  DATA: t1 TYPE i
      , t2 TYPE i
      , CNT TYPE i
      .
 
  CNT = 0.
 
  GET RUN TIME FIELD t1.
 
  SELECT  *
        INTO    ls_mseg
        FROM    mseg AS m
        WHERE
    NOT EXISTS (
    SELECT  *
    FROM    mseg
    WHERE   smbln = m~mblnr
      AND   sjahr = m~mjahr
      AND   smblp = m~zeile
    )
        .
 
*    SELECT  SINGLE mblnr
*    INTO    ls_mseg-mblnr
*    FROM    mseg
*    WHERE   smbln = ls_mseg-mblnr
*      AND   sjahr = ls_mseg-mjahr
*      AND   smblp = ls_mseg-zeile.
*    CHECK sy-subrc <> 0.
 
    CNT = CNT + 1.
  ENDSELECT.
 
  GET RUN TIME FIELD t2.
 
  t2 = t2 - t1.
 
  WRITE: / 'EXECUTION TIME:', t2.
  WRITE: / 'RECORDS COUNT:', CNT.

Комментарии

Популярные сообщения из этого блога

Прямые ссылки на файлы Google диска

В предыдущей статье я рассказал, как подключить свой JavaScript файл к блогу BLOGSPOT . Но для того, что бы их подключить нужны прямые ссылки на файл, а Google диск при предоставлении общего доступа к файлу выдает ссылку на предварительный просмотр, которая никак напрямую не ссылается на файл. Для Google диска прямая ссылка на файл - это ссылка на скачивание. Ниже описаны два способа создания ссылки на скачивание на примере файла prism.js.

События для ведения таблиц

Как и всегда, в пылу проекта внезапно родилась Z табличка. Главный нюанс был в том, что она должна была хранить пароли для авторизации на стороннем сервере. Естественно, никто не хотел хранить пароли в открытом виде, а двустороннее шифрование SAP не умеет без сторонних пакетов и надстроек. Далее, все как обычно - придумали алгоритм, сделали табличку. Дело осталось за малым - нужно шифровать пароли, которые вводит пользователь. Делать отдельную программу нет смысла, поскольку ее функционал мало чем будет отличаться от сгенерированного. Вот здесь на помощь приходят события! С их помощью можно, наверное, все. По крайней мере, я не нашел чего-либо, что нельзя сделать с данными через события.

OOP ALV GRID с HTML шапкой

В этой статье хочу постараться подробно описать и привести пример, как можно создать ALV отчет с таблицей на весь экран и с HTML шапкой вверху. Я не буду описывать начальный этап, где пишется селекционный экран или делается выборка данных. Будем считать, что основа у нас есть и нам нужно просто вывести данные. Главной изюминкой является то, что нужно вывести ALV GRID на экран без использования каких-либо дополнительных элементов на экране. Step-By-Step Шаг 1. Создание окна Создаем самое простое окно с номером 100. На него не нужно кидать никаких контейнеров. Оно нам нужно только для модулей PAI и PBO и вывода на него ALV GRID.