понедельник, 17 августа 2020 г.

SAP ABAP: анализ производительности


Транзакции для анализа производительности

ST04 - различная информация о базе данных
Самые популярные пункты в st04:
* Addition functions / sql command editor - можно запустить произвольный sql
* Shared cursor cache - abap source - переход по sql_id к конкретной части кода, где он вызывался

ST12 - запуск трассировки
* для пользователя на любом сервере
* планирование трассировки на время в будущем по условию

SM37 - информация и поиск фоновых запусков: пользователь, программа, время работы
* просмотр параметров job: step - goto- variants

Если запусков много, то удобней их анализировать напрямую обращаясь к таблице с логом запуска:
select TBTCO.JOBCOUNT, TBTCO.STEPCOUNT, TBTCO.STRTDATE, TBTCO.STRTTIME, TBTCO.ENDDATE, TBTCO.ENDTIME, TBTCO.RELUNAME ,
to_date(TBTCO.ENDDATE || TBTCO.ENDTIME, 'yyyymmddhh24miss')-to_date(TBTCO.STRTDATE || TBTCO.STRTTIME, 'yyyymmddhh24miss') as sec
from TBTCO 
where TBTCO.jobname = 'ZHR_UPLOAD_ETWEB2' 
and length(TBTCO.STRTTIME) > 1
order by TBTCO.STRTDATE desc, TBTCO.STRTTIME desc

SE38 - запуск программы "/SDF/SMON"
* сэмплирование загруженности серверов: CPU, ОЗУ, число занятых процессов и т.д.
можно анализировать запросом к бд:
select * from  "/SDF/SMON_WPINFO"

* в каждой строке детализация по аналогии с ASH - информация о программе, фоне, обращении к таблице и типе ожидания
также можно налаизировать запросом
SELECT "SCHEDULEDATE", COUNT(*) FROM "/SOMO/JOBMON11" 
group by "SCHEDULEDATE"
order by 1 desc

STAD - максимально подробная статистика работы программы, но на коротком промежутке времени

ST03 - статистика работы программ но на длинном промежутке времени: дния/недели

SM66 - список всех процессов по всем серверам
в детализации можно посмотреть текущий стек вызова

SE80 - поиск программы/функции или таблицы по части имени

ST22 - список системных дампов (программы упавшие с ошибкой)

ST06 - история нагрузки CPU на длинном промежутке времени
RSMEMORY - информация о доступной памяти на сервере
RZ04 - лимит на число процессов по типам
SU01 - соответствие логин-пользователь

Буферизация таблиц

Буферизация используется, чтобы при обращений к таблицам из abap обращение шло через кэш без обращения к БД.
Буферизация может быть на полную таблицу или на часть по ключу:
* generic buffering
* single rec buffering
При обращении к таблице есть ограничение на SQL

Кэш сохранятся в таблице "DDLOG"
Синхронизация кэша между северами приложений происходит каждые 1-2 минуты фоновым заданием.
Исходя из ограничение консистентности между серверами и ограничение на SQL, буферизация может использоваться в небольшом числе запросов, в основном на справочниках.

ST02 - данные о буферах и % их срабатываний
ST10 - информация о таблицах в буфере
AL12 - содержимое буфера
monitor - buffer - table buffer - buffer content
* Сброс буфера
сбросить все буфера - /$SYNC
сбросить буфера таблиц - /$TAB
сбросить буфер конкретной таблицы se38 - SBUF_TBX_RESET (SYNC = X, RESET = X)

Популярные проблемы в abap коде

Пара проблем, которые может определить трассировка:

Обращение к внутренней таблице без ключа

Нужно отсортировать таблицу по ключу поиска и сделать BINARY SEARCH.
Это уменьшит стоимость обращения к таблице с N до Log2(N)

Повторяющиеся запросы

Если трассировка показывает у топового запроса большое кол-ва identical повторений. (Это когда запрос выполнятся с одними и теми же параметрами в цикле).
Варианты:
* Стоит пересмотреть логику работы, чтобы исключить повторные запуски
* Создать внутренний объект сортированный по ключу поиска для хранения промежуточных результатов
** При первом обращении к таблице в БД заполнить внутреннюю таблицу
** При последующих проверять на наличии записи в кэше по ключу
** Если запись есть в кэше, то брать из него, если нет, то выполнять запрос к базе и дозаполнять кэш

Запросы в цикле

Запрос в цикле оптимальней заменить на общий запрос через "for all entries"
Это снизить время на установку соединения с базой и время на передачу данных по сети.
for all генерируется пачки запросов к БД объединяя несколько параметров поиска в 1 запрос. Исопльзуется IN или OR.

Abap хинты

Можно увеличить число записей в for all, используя хинт:
%_hints oracle '&max_in_blocking_factor 20&'

Если в запросе сильный перекос в данных, то бинды в запросе можно заменить на литералы хинтом:
%_HINTS ORACLE 'SUBSTITUTE VALUES'.

Также можно указывать обычные Oracle хинты через abap:
%_HINTS ORACLE 'full("WALE")'.
%_HINTS ORACLE 'index("WALE~0")'.

2 комментария: