Интернет проект
SAP Professional Journal Россия

Практические рекомендации по оптимизации программ на ABAP

Практические рекомендации по оптимизации программ на ABAP

Функциональная область:

IT, Basis, ABAP / Managment IT

Ролевое назначение:

SAP Консультант / Consultant

Ключевые слова:

разработка на ABAP / ABAP Development / ABAP

Практические рекомендации по оптимизации программ на ABAP

Практические рекомендации по оптимизации программ на ABAP


 

Точенюк Олег занимал должности консультанта по SAP ММ в различных компаниях, с 1997 года, занимался внедрением модулей FI-FM (контроль исполнения бюджета), Управления материальными потоками (ММ), Управление складом СУС (WMS), был консультантом по интеграции MM<->ТОРО, занимался разработками расширений системы на языке ABAP. Связаться со мной можно по адресу uukrul@hotmail.com

 

В статье изложены практические принципы по оптимизации работы программ на ABAP, приведено сравнения быстродействия вариантов программ.

Категории: Язык ABAP

«Ну и запросы у вас, сказала база данных и повисла».

(Саперская мудрость)

Как поется в песне: «Не прожить на этом свете» без ABAP; приходится писать отчеты/обработки/экзиты, которые долго «гудят», «съедают» память, загружают процессор, и в результате мы имеем недовольных пользователей и медленную систему. Много есть консультантов - функциональщиков, которые писать на ABAP ничего не собираются, этот их выбор мы уважаем (хотя и не одобряем). Настоящая статья предназначена как раз для тех, кто пишет или хочет научиться писать на ABAP правильно. Итак, поговорим об оптимизации или как писать «быстрые» программы. Но учтите: иногда достаточно одной, не совсем правильно написанной, проверки в экзите, чтобы «тормознуть» работу системы в разы.

Некоторые вопросы оптимизации очень специфичны, и если у меня в тесте, что-то работает быстрее, это не значит, что этот эффект повторится у вас. Но большинство операций описанных ниже, будут корректными в общем случае (для всех систем).

В нашем случае под оптимизацией будем понимать написание оптимального по исполнению кода на языке ABAP, а не оптимизацию способа выбора данных из таблиц системы. Конечно же, второй из указанных, тип оптимизации зачастую будет быстрее, но это при наличии следующего условия: вы знаете, в какой таблице находятся нужные вам данные, в требуемом разрезе. Выбрать их из этой таблицы будет быстрее, чем найти, обработав десяток таблиц. Но это, как говорится, другая история; для каждой функциональности она имеет свои особенности.

Часть информации, содержащейся в тексте, приведенном ниже, есть в справке к системе но тем не менее смысл всего изложенного и опыт ивместе добыт «кровью и железом», поэтому ценен.

Для понимания текста, желательны хотя бы минимальные знания языка ABAP, хотя бы в рамках обзора книги "Разработка приложений SAP R/3" авторы Рюдигер Кречмер и Вольфганг Вейс.

1. Выбор данных для обработки во внутренние таблицы.

Время диалоговых процессов в системе, как известно, ограничено. Стандартно диалоговых процесс в системе может длиться не более 600 секунд и дальше ваша задача будет завершена принудительно, правда на практике, администраторы системы это время обычно увеличивают, но и мы можем тоже, кое-что «докрутить» в своих запросах, чтобы они работали чуть быстрее. Итак, есть таблица MKPF — заголовки документов материала. Вариантов выбора и обработки значений – два; первый: в цикле оператора SELECT.- ENDSELECT., второй: выбор во внутреннюю таблицу и затем обработка данных в цикле оператора LOOP AT <внутренняя таблица>. ENDLOOP. Кроме того, для этих операторов есть различные варианты вызова.

Для тестирования будет использоваться внутренняя таблица.

Варианты выборки данных.

Если структура, куда выбирают данные, совпадает со структурой из выбираемой таблицы, то можно выбрать данные наиболее быстрым способом:

При реальных запросах, не все поля находящиеся в таблице MKPF, нужны во внутренней таблице LT_MKPF, тогда такую структуру надо объявить с перечислением только используемых полей. Если это сделано так, то нужно использовать расширение операции INTO в виде «INTO CORRESPONDING FIELDS OF» т. е., система сама разложит результат, сделав правильное соответствие выбираемых полей из таблицы, полям в структуре. При этом если выбираются все поля, то время выполнения различается в пределах 0,1%, но при этом всегда время выполнения первого запроса меньше чем второго.

Как видим, разница в быстродействии практически отсутствует, но если выжимаем максимум, то запрос A1 предпочтительнее, опять же, «копеечка рубль бережет».

Как уже отмечалось выше, более предпочтительнее выглядит данный запрос, если нам нужны не все поля из таблицы, например, хотим выбрать следующие поля: MBLNR — номер документа, MJAHR — год документа, XBLNR — ссылочный номер, BKTXT — краткий текст заголовка документа. Тут уже время отличается и существенно.

Как видим скорость выборки стала в среднем в 4 раза быстрее. Однако если сделать следующий вариант вызова, когда внутренняя таблица содержит только необходимый набор полей, то, как видим, операция «INTO TABLE» будет быстрее, в среднем от 15% до 20%.

На скорость выборки, в случае перечисления выбираемых полей, влияет также порядок их следования. Если порядок следования полей внутренней таблицы такой же, как и в таблице базы данных, то скорость выбора будет быстрее, если вы выбираете все поля. Например, требуется выбрать все поля из таблицы MKPF.

Как видим перечисление всех полей с оператором «CORRESPONDING FIELDS», работает чуть быстрее, чем операция «INTO TABLE», разница не существенна, но опять же если выжимать максимум, то следует задуматься. Однако если вы вдруг перепутаете порядок следования полей, то получите вместо ускорения запроса, наоборот его замедление.

На разных выборках время выполнения запроса H1, фактически стало равно времени выполнения запроса G1.

Описанные выше комбинации работают быстро, однако грузят все данные в память - ресурс, который, может закончиться, причём в самый неподходящий момент. Поэтому иногда приходится жертвовать производительностью, но при этом оптимизировать использование памяти. Для этого данные обрабатываются по ходу их считывания в конструкции SELECT <>. ENDSELECT.

Как видим время выполнения данного запроса больше (у меня эти колебания были в среднем от 10% до 15%). Но что касается экономии памяти, такая конструкция - вне конкуренции. Несомненно, время выполнения будет быстрее, если перечислить в запросе только поля, которые нам нужны.

Как видим, скорость выполнения запроса J1 в среднем в три раза выше, чем скорость выполнения запросов I1. По поводу перечисления полей и порядка их следования, правила такие же, как и для запросов F1 и H1, порядок следования полей важен.

Выводы по скорости: Наиболее быстрым будет вариант выбора данных во внутреннюю таблицу с использованием запроса вида E1, при этом внутренняя таблица должна содержать только те поля, которые нам необходимы для работы. Желательно чтобы порядок следования полей, совпадал с порядком следования полей из выбираемой таблицы.

Выводы по памяти: Если у вас хватает памяти, то конструкция выбора всех данных в память с последующей обработкой будет предпочтительнее, чем их построчная обработка. Для оптимизации использования памяти, выбирайте и определяйте в структурах только те поля, которые вам нужны для обработки. Из практики, мне только раз встретилась система, где не то чтобы памяти было мало, но данных было очень много, поэтому пришлось оптимизировать память, жертвуя скоростью выполнения запроса.

2. Использование агрегатных функций.

Агрегатные функции - это использование таких конструкций как SUM, COUNT, MAX и т. д. в запросах. Сложно однозначно предсказать, что будет быстрее: выбрать данные во внутреннюю таблицу и посчитать все самому или же попросить, чтобы все посчитала база данных. Также, наблюдается зависимость работы данных функции от типа базы данных, на которой работает система. Данные тесты проводились для базы данных DB6, Рис.1. Большая вероятность, что для других баз данных результаты будут отличными, от полученных в данном описании.

 
Рис. 1 Database

В общем виде ситуация следующая, есть запрос вида

Мы считаем, сколько штук всего было оприходовано по всем документам, при этом я убрал автоматически добавляемые позиции из запроса. Сделаны запросы следующего вида:

В среднем время выполнения второго запроса B2, оказывается быстрее, чем при использовании агрегатной функции, хотя приходится написать «больше» кода и выглядит он «не так красиво» как в запросе A2. В среднем после более чем десяти прогонов, время выполнения запроса B2 было быстрее от 7% до 15%. Итак в среднем, выигрыш в скорости работы составляет около 10%

Примечание: Об оптимизации циклов по внутренним таблицам, будет рассказано ниже. Использование оптимизации такого рода даст дополнительный прирост производительности для запроса B2.

С функцией COUNT результат еще интереснее

По факту, скорость выполнения запроса D2 меньше, чем выполнения C2. При этом после 50 прогонов в двух случаях зафиксировано, что запрос скорость запроса D2 была почти равна скорости запроса С2. Среднее значение ускорения скорости выполнения запроса в процентах, по сумме прогонов получилось в районе от 10% до 15%.

Функции же MIN и MAX показывают обратный результат, т. е. запрос к базе отрабатывает быстрее, чем локальная обработка.

Однако, если в запрос E2 добавить сортировку, используя конструкцию ORDER BY, (т. е. исключаем локальную сортировку после запроса), как в примере запроса G2, то скорость практически была такой же, как и запроса F2. Индексов на поле, по которому выполнялась сортировка, не было. В целом, разница по скорости выполнения для запросов E2 и F2, колебалась в районе от 3% до 5%.

Примечание: При проверке работы агрегатных функций для базы данных Oracle 9, по таблицам COSS/COCP/COEP, функция суммирования работала быстрее, чем локальная выгрузка во внутренние таблицы с последующей обработкой в цикле по внутренней таблице. При проверке суммирования, GROUP BY был по индексу.

Выводы по скорости: Так как работа агрегированных функций очень специфична в зависимости от используемой базы данных, то сделайте тестирование работы этих функций на своей системе, чтобы определить наиболее быстрый вариант. Для текущей используемой системы рекомендации оказались следующими, для функций COUNT и SUM по возможности нужно было использовать локальную обработку, с чтением данных во внутренние таблицы и последующим расчетом, после запросов, а для функций MIN и MAX, наоборот, лучше оказалось выполнять обработку, используя их.

Выводы по памяти: С точки зрения использования памяти, всегда наиболее оптимальным будет вариант использования агрегированных функций, так как в этом случае все расчеты идут на уровне запроса к базе данных.

3. Ограничение выборки в условиях WHERE.

Стандартная рекомендация: если вы можете ограничить выборку по каким-то полям, то сделайте это. Скорость обработки, будет выше, чем проход по всей таблице, без каких либо ограничений, с последующим выбором нужных данных из внутренней таблицы. Как минимум, выигрыш будет на количестве пересылаемых данных от сервера к клиенту, в том случае, когда по полям ограничений в условии WHERE нет никаких индексов, и выполняется полный проход по всем записям таблицы. Конечно, более логичным будет при формировании условия отбора обратить внимание на наличие индексов к таблице. После чего сформировать запрос так, чтобы оптимизатор не ломал голову, какой индекс использовать, т. е. при перечислении полей в условии WHERE, используйте порядок такой же, какой существует в подходящем индексе. В общем случае данное утверждение спорно: результат зависит от типа используемой базы данных и статистики индекса, если подходящих индексов несколько. Из классики:

Как видим, запросы с ограничением условия в WHERE, работают в разы быстрее. Кстати, не забываем при использовании довеска «FOR ALL ENTRIES IN» делать проверку на наличие данных в таблице, используемой в условии. Потому что, если данных там нет, то будет выполнен полный проход по таблице выборки, а это плачевно отражается на скорости выбора данных, даже если вам нужно получить все записи.

Как видим, простой проход по таблице выполняется быстрее, чем тот же самый проход, но с пустой таблицей в условии FOR ALL ENTRIES. Поэтому отслеживайте, чтобы таблица в таком случае не была пустой. Если в ходе работы программы у вас может возникать такая ситуация, то более правильным будет сделать два запроса в программе, в зависимости от заполнениия таблицы lt_meins.

При задании ограничения по полям очень важно, чтобы в системе были подходящие индексы, иначе при запросе система будет выполнять полный проход по таблице. Наличие индексов к таблицам можно посмотреть в транзакции SE11. В режиме просмотра данных таблицы, на панели инструментов есть кнопка «Индексы», Рис.2.

 
Рис. 2 SE11-4

Кроме показанных в списке индексов, где первая колонка это имя индекса, всегда существует еще так называемый индекс первичного ключа с именем «0», в этот индекс входят все поля, которые отмечены в таблице как ключевые. В данном случае, для таблицы MKPF, существует только один дополнительный индекс, построенный по дате проводки документов материала. Для просмотра данных индекса сделайте двойной клик в строке.

Во время построения запроса, оптимизатор базы данных, анализирует поля в условии WHERE и старается найти подходящий индекс, если такой не найден, то будет выполнен полный перебор записей таблицы, что конечно же катастрофически скажется на скорости выбора данных. Для большинства баз данных, порядок перечисления полей в условии WHERE не важен, т.е. если есть индекс по полям 1 и 2, а в ограничении порядок полей стоит 2 и 1, то оптимизатор «теоретически» найдет правильный индекс и будет его применять. Для базы DB2 это правило работает. Так же оптимизатор старается подобрать индекс, если есть не полная совместимость по используемым полям, т.е. к примеру, индекс содержит только некоторые из полей WHERE или же, наоборот, в индексе содержится больше полей, чем в запросе. При наличии нескольких подходящих индексов, система будет использовать тот индекс, у которого лучшая статистика. Статистику индекса умеют собирать системные администраторы базы данных. В общем виде статистика, в терминах системы «Estimated Costs» есть число, значение которого рассчитывается в зависимости от величины различных (неодинаковых) записей в таблице (чем оно меньше, тем более лучшим считается индекс).

По возможности, следует избегать оператора NOT в условиях, так как при использовании такой конструкции поля определенные через NOT не обрабатываются как пригодные для индекса. Поэтому нужно стараться избегать операции отрицания. Это относится и к операциям не равно – «<>», такие поля также пропускаются индексом. Для приведенного ниже примера использовалась таблица MSEG с анализом использования индексов в транзакции ST05. В системе создан завод U100 и для этого завода созданы два склада с кодами 0001 и 0002. Простым запросом выбираем документы, проведенные по одному или другому складу. Например, выберем документы, проведенные по складу 0001.

Как видим простое указание, выбирать документы, где завод не равен 0002, т.е. только документы с заводом 0001, приводит к значительному увеличению времени работы запроса. Поверьте что завода там действительно только два. Причина увеличения времени кроется в выборе индексов для запросов E3 и F3. Для запроса E3 система использовала созданный индекс по заводу и складу с именем MSEG~TST, Рис.3.

 
Рис. 3 ST05-TST-0

Для запроса F3, этот индекс уже не использовался; как видим, был взят индекс MSEG~M, причем в этом индексе использовалось только одно поле с кодом завода, данные кода склада: <> 0002 были вообще пропущены, Рис.4, т.е. фактически, оптимизатор выбирал индекс исходя из поля «Завод», и совсем не интересовался полем «Склад».

 
Рис. 4 ST05-TST-2

Исходя из построения плана запроса, можно сделать следующий вывод: если для завода будет создано много складов (например, завод 2200 в IDES содержит более 30 складов) и стоит задача выбрать все документы, за исключением склада 0001, более правильным будет перечислить в условии все склады, используя команду IN, за исключением склада 0001, чем указать в условии значение «не равно складу 0001».

Как видим, скорость в выполнении запросов существенно различается. Это происходит потому, что для запроса H3, использовался не тот индекс, по аналогии с рисунком 4: ST05-TST-2.png Хотя писать запрос G3 дольше, но (в качестве примера) можно использовать переменную типа RANGES: выбрать в нее все нужные склады завода 2200 и удалить лишние, например 0001.

Выводы по скорости: Если возможно, то при любых запросах к базе данных, стараемся ограничивать объем выбираемых данных, используя конструкцию WHERE, при этом особое внимание обращаем на наличие индексов по полям, участвующих в ограничениях выбора, так как это значительно ускоряет обработку данных. Не используйте в ограничениях WHERE операции отрицания NOT или не равно («<>»), раскладывайте эти конструкции на более понятные для оптимизатора варианты: равно или операцию IN. Иначе, при выборе система будет выполнять полный проход по таблице данных или будет использовать некорректные для данной ситуации индексы.

Выводы по памяти: При выборе данных во внутренних таблицах ограничение WHERE всегда позволяет получить из базы меньший объем данных, и соответственно, получить меньшие затраты по используемой памяти, в случае выбора данных во внутренние таблицы. Поэтому, даже если у вас нет подходящих индексов, но есть ограничение по памяти, использование ограничений WHERE желательно, так как не имеет смысла загружать лишние данные во внутренние таблицы, для их последующего исключения из обработки локально.

4. Проверка наличия значения в таблице.

Фактически это данные справки системы SAP, но «кто же читает инструкцию на холодильник до начала его эксплуатации». Рассмотрим задачу проверки наличия записи по определенным ключам в таблице. Привожу варианты из классики (системы).

В среднем, скорость работы разнится от 6 до 8 раз, так что не забываем такой оператор как UP TO ROWS и уже ни в коем случае не используем для проверки наличия агрегатную функцию COUNT( * ), иначе результат будет совсем грустным.

Еще один способ проверить наличие значения в таблице - это использовать конструкция SELECT SINGLE. Скорость выполнения запроса D4 будет аналогичная запросу B4. С точки зрения интерфейса к базе данных, оба запроса B4 и D4 выдадут одинаковую инструкцию на уровень базы данных. Однако если использовать расширенную проверку программы, транзакция SLIN, то будет сгенерировано следующее предупреждение:

Суть предупреждения, сводится к тому, что для запросов вида SELECT SINGLE, система предполагает всегда задание уникального ключа в условии отбора WHERE, в данном же случае, ограничения условия WHERE в запросе не обеспечивают такой уникальности, и система сообщает, что может существовать более одной записи для запроса. Так как это предупреждение выдается только при расширенной проверке программы, то дело разработчика, обращать на него внимание или нет.

Выводы по скорости: Для проверки наличия значений в таблице, используем конструкцию с UP TO ROWS. Кстати, документация по разработке SAP, так же рекомендует данную инструкцию.

Выводы по памяти: Для оптимизации памяти, если мы проверяем только наличии записи в базе данных, вместо выбора всех полей лучше указать одно поле, например, CARRID. Такая конструкция, влияет и на скорость обработки, при этом замечена следующая закономерность, время запроса B4 уменьшается на 6-7 микросекунд, а запроса D4 на 10-11 микросекунд, т.е. время запроса D4 после 50 тестовых прогонов было всегда меньше, хотя 4-5 микросекунд, величина практически неощутимая.

5. Буферизация чтения данных

Если имеются часто изменяемые данные в таблицах, например это очереди в таблице сообщений, то читают такие данные обычно с выключением буфера. Однако не следует ”перебарщивать”, иначе скорость обработки будет печально мала.

Выводы по скорости: Если нет нужды, не отключаем буферизацию чтения данных. Для некоторых таблиц базы (обратите внимание) операции чтения одинаковы, независимо от наличия директивы BYPASSING BUFFER, это связано с техническими параметрами настройки таблиц участвующих в запросе, для просмотра технических параметров таблиц, можно воспользоваться транзакцией SE13, Рис.5. Как видим, для таблицы MSEG буферизация запрещена, а для таблицы T100, буферизация разрешена, поэтому для таблицы MSEG директива BYPASSING BUFFER неактуальна.

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

 
Рис. 5 SE13

6. Объединение таблиц в запросах.

Теория языка SQL, рассматриваться не будет, а из практики, точнее «по классике» ситуация выглядит так.

Как видим, вложенные запросы работают быстрее, чем выборка с использованием объединения, хотя если несколько переделать запрос, то результат будет выглядеть иначе.

Как видим, скорость выполнения увеличивается, однако при объединении таблиц, сначала нужно определиться с объемами данных, которые в них находятся. Если требуется, по возможности, ограничивать выбираемые данные, то ограничение будет тем качественнее, чем на более высоком уровне будет сделано, т. е. ограничение по таблице MKPF предпочтительнее (по MSEG - на уровень ниже).

Выводы по скорости: В данном случае мне сложно что-то советовать, это уже тема, связанная с хранимыми данными, а в начале статьи было сказано, что такой оптимизации особого внимания не будет уделено. В целом, как видим, объединение с чтением во внутреннюю таблицу или хотя бы во внутреннюю переменную выполняется быстрее, что следует из первой темы статьи, но при этом наблюдается зависимость скорости от количества данных находящихся в таблицах.

При выполнении соединения, важным условием является наличие индексов по полям соединения таблиц. В большинстве случае, при наличии нужных индексов, оптимизатор базы данных правильно выбирает необходимые индексы и делает соединение. Однако в некоторых случаях, создается ситуация, когда нужно явно указать использование индекса, для чего в запросах есть специальная команда %_HINTS. В случае базы данных Oracle при выборе из таблицы MARA, например, нужно принудительно использовать индекс с именем «Т», тогда запрос будет иметь следующий вид:

Администраторы базы данных этого сильно не любят, потому что в принципе, оптимизатор должен сам решать как делать выборку основываясь на статистике индекса и своих внутренних алгоритмах. Кроме того, если индекс жестко не привязан к запросу, то администратор может управлять процессами выбора индексов через средства управления сервером базы данных, а вот при жесткой привязке индекса ему этого уже не сделать.

Выводы по скорости: Если вы не уверены, в результатах своих действий, лучше расширение типа %_HINTS в запросах не использовать, а если решили применить такую конструкцию, то обязательно сообщите об этом администратору базы данных.

Как следует из опыта соединения таблиц и подзапросов, при больших объемах данных вложенные запросы существенно замедляют быстродействие основного. Однако как быть с решением такой, например, задачи: «Выбрать документы материала с исключением из выборки сторнированных документов». Исходя из структуры данных и того как система хранит признак сторно, это не просто при большом объеме документов, более > 1.000.000 позиций, так как в позиции прямого документа в таблице MSEG нет ссылки на сторнирующий. Поэтому построенный обычный запрос по загрузке данных во внутреннюю таблицу с последующим отсечением сторнированных документов в цикле по полученным записям (используя единичную выборку из MSEG (SELECT SINGLE ...), а при положительном ее результате (sy-subrc = 0) удаляя позиции из внутренней таблицы) оказался неприемлемым. Система «падала в дамп» по таймауту. Поэтому в этом случае, подзапросы оказались более оптимальными, чем локальная обработка внутренних таблиц. Конечный запрос имел такой вид.

Таков частный случай оптимизации с использованием подзапросов. Вполне возможно, что для вашей системы этот запрос может быть не оптимальным.

Выводы по скорости: Всегда нужно моделировать несколько вариантов выполнения выборок, вполне возможно, что более медленная в общем виде конструкция, на ваших данных окажется оптимальной. В нашем случае так же есть и неявный выигрыш в скорости дальнейшей обработки полученных данных, так как не нужно делать отдельное удаление сторнированных документов из внутренней таблицы.

Выводы по памяти: С точки зрения памяти, использование подзапросов, более оптимально, так как уже на уровне базы данных выполняется исключение всех не нужных во внутренней таблице записей, т.е. внутренняя таблица, по факту, будет сразу содержать только требуемые данные.

Соединение большой таблицы с относительно маленькой. Такие задачи обычно возникают часто при построении отчетов. Наиболее типичная ситуация, например, у нас есть позиции документа материала. В каждой позиции есть код единицы измерения. Клиент требует, чтобы в отчете была колонка с полным текстом наименования единицы измерения. Варианты реализации этого требования следующие.

Выполним выборку основных данных из таблицы MSEG – позиции документа материала, а затем в цикле для каждой позиции прочитаем по краткому коду единицы измерения ее полный код и запомним его во внутренней таблице.

Сделаем то же самое, но теперь используем соединение таблиц MSEG и T006A, код будет значительно короче и выполняться будет быстрее

Значительно лучше, но данные результаты можно еще улучшить, для этого модифицируем запрос G6. Путем вынесения чтения списка единиц измерения в отдельный запрос и затем в цикле будем читать данные из внутренней таблицы.

Как видим, скорость выполнения этого запроса самая минимальная. Однако есть еще один вариант решения данной задачи, состоящий в том, чтобы объединить варианты G6 и I6.

Т.е. суть выборки заключается в том, чтобы выполнять выбор единиц измерения из базы данных только в том случае, когда во внутренней таблице измерения нет нужной нам величины. В данном случае этот вариант оказался немного медленнее, чем вариант I6, но это связано с тем, что тесты делаются на системе IDES и в проводках документов материала из возможных 260 единиц измерения используются 76. В большинстве же реальных систем, наверное, количество вариантов использования единиц измерения будет меньше, соответственно количество запросов SELECT SINGLE xxxx FROM T006A будет тоже меньше и вполне возможно, что запрос J6 будет самым быстрым. Это как раз и есть тот случай, когда нужно моделировать запросы на клиентских данных. Также способ обработки I6 будет более быстрым, если справочными таблицами, будут такие таблицы как основные записи материала или дебиторов/кредиторов, при этом выигрыш будет очень значительным, так как обычно в периоде работы редко используются все существующие в системе коды материалов или дебиторов/кредиторов.

Примечание: В данном случае при чтении данных в операторе READ TABLE не использовалось расширение BINARY SEARCH, так как таблица lt_t006a не была объявлена как сортированная, а для несортированных данных использовать такой поиск нельзя. Более подробно о том, как идет выбор данных, из внутренних таблиц, рассмотрим в той части статьи, где будут описаны способы объявления таких таблиц.

Выводы по скорости: При соединении большой таблицы со справочниками (справочными таблицами, содержащими относительно основной таблицы минимальный набор значений), более оптимальным будет использование отдельного чтения значений справочников во внутренние таблицы с последующей ручной обработкой соединения в цикле LOOP AT . ENDLOOP. Если же использовать объединение основной таблицы, со справочными, используя оператор JOIN в одном запросе выбора данных, то это может несколько замедлить выбор данных, хотя и не слишком, так как обычно справочные таблицы буферизированы. Проверить буферизацию таблиц можно используя транзакцию SE13.

Выводы по памяти: С точки зрения оптимизации памяти, более выгодным будет использование хранения справочных данных в отдельных внутренних таблицах, без использования объединения чтения данных одним запросом в большую внутреннюю таблицу, содержащую все необходимые данные. Примеры такого чтения показаны в запросах I6 и J6, где данные справочника текстов единиц измерений, лежат в отдельной внутренней таблице.

7. COMMIT WORK.

COMMIT WORK в общем случае производит фиксирование измененных или добавленных в базу данных. В системе, есть два варианта использования COMMIT, это собственно сам COMMIT WORK и кроме того специальный функциональный модуль «DB_COMMIT». Функциональный модуль вызывает операцию фиксирования изменений на уровне базы данных; собственно говоря, там используется внутренний запрос к базе данных, используя блок:

При этом в случае ошибки применения изменений, вы не можете получить никакие сообщения, т.е. этот ФМ отработает, но вот узнать, как произошла операция, и в случае ошибки выполнить ROLLBACK будет невозможно. Поэтому в системе введена специальная команда COMMIT WORK, которая на самом деле выполняет не только фиксацию измененных данных, но и выполняет еще следующие полезные действия:

 

  • Выполняет запуск всех подпрограмм, которые вызываются с использованием инструкций вида PERFORM <имя подпрограммы> ON COMMIT и всех функциональных модулей объявленных как CALL FUNCTION <имя модуля> IN UPDATE TASK.
  • Вызывает инициирование событий для службы Object Services. Поэтому если у вас есть фоновые процессы, запускающиеся по событию, то именно эта операция генерирует все заявленные в блоке обработки события.
  • Обрабатываются все SAP блокировки, установленные в текущей программе по значению формального параметра _SCOPE для соответствующих функций блокирования, происходит снятие таких блокировок.
  • Закрывается текущий LUW блок и все курсоры на уровне базы данных.
  • Вызывается событие TRANSACTION_FINISHED, что устанавливает для системного класса CL_SYSTEM_TRANSACTION_STATE значения COMMIT_WORK.

 

При массовых вставках или изменениях данных, не следует использовать COMMIT WORK после каждой вставки или изменения данных. Так же не следует «заливать» все данные и делать один об

 
Любое воспроизведение запрещено.
Копирайт © «Издательство ООО «Эксперт РП»
Support Письмо  
 

Фильтр

Ещё по теме:

ABAP Performance Tuning

2 200 руб.
Заказать

Еще материалы

Карта сайта

 
Путеводитель
по порталу SAPLand

Содержание портала представляет собой уникальное, непрерывно пополняемое хранилище знаний и решений в различных областях SAP.

Предназначение портала:

  1. Распространение профессиональных знаний;
  2. Сбор и агрегирование (определение лучших) решений по SAP;
  3. Формирование экспертами ответов на самые сложные вопросы внедрения и применения сиcтемы SAP.

Подробнее →

  • ico
    Поиск по Порталу
  • ico
    Статьи и рекомендации
    Статьи и рекомендации

    В разделе «Статьи и рекомендации» специалисты найдут решения и рекомендации, которые они смогут применить при внедрении и эксплуатации системы SAP.

    Перейти →

  • ico
    Новости
    Новости

    В разделе «Новости» регулярно публикуется информация о текущих событиях на рынке SAP.

    Перейти →

  • ico
    О портале
    О портале

    В разделе «О портале» посетители портала найдут информацию о концепции портала, о компаниях - партнерах портала и наши контактные данные.

    Перейти →

  • ico
    Материалы SAP CIS
    Материалы SAP CIS

    В разделе «Материалы SAP CIS» и специалисты, и менеджеры найдут материалы мероприятий, проведенных компанией SAP. В этом же разделе посетители, желающие пройти обучение на курсах компании SAP, найдут всю необходимую информацию.

    Перейти →

  • ico
    Решения партнеров
    Решения партнеров

    В разделе «Решения партнеров» и менеджеры, и специалисты найдут описания лучших решений консалтинговых компаний. Все решения прошли проверку внедрением.

    Перейти →

  • ico
    Магазин
    Магазин

    Сервис раздела «Магазин» дает возможность всем посетителям приобрести любые книги издательства SAP Press на английском языке, книги по SAP на русском языке, подписки на журнал SAP Professional Journal Россия и базы знаний SAP Experts, а также мультимедийные курсы по SAP.

    Перейти →