SAPфорум.RU
https://www.sapboard.ru/forum/

Игнорирование буфера/кэша БД при select
https://www.sapboard.ru/forum/viewtopic.php?f=13&t=97458
Страница 1 из 2

Автор:  Saperx [ Пт, мар 15 2019, 13:39 ]
Заголовок сообщения:  Игнорирование буфера/кэша БД при select

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

При первом прогоне ситуация в тесте практически такая же плачевная, как и продуктиве.
Тест:
Total Number of Executions - 27
Execution Time of SQL in microseconds - 220 194 416
Number of Records Processed - 3 361
Time per Execution - 8 155 349
Records per Execution - 124,5
Average Processing Time per Record - 65 515

Прод:
Total Number of Executions - 33
Execution Time of SQL in microseconds - 245 921 941
Number of Records Processed - 3 388
Time per Execution - 7 452 180
Records per Execution - 102,7
Average Processing Time per Record - 72 586

Если же попытаться, повторно сделать трассировку, то в тестовой системе видимо уровне БД(т.к. настройка буферизации в se11 для таблицы не включена, да и запрос с джоином и через FAE), происходит буферизация и запрос отрабатывает оч. быстро(за пару секунд). При этом этот буффер может висеть часами в тесте(в проде уже через пару минут ситуация аналогична холодному запуску), в итоге приходится дожидаться когда БД посчитает буфер инвалидным и выгрузит таблицу. Только после этого есть возможность опять запустить выборку в тестовой системе и проверить примененные изменения.
Понятно, что при таком режиме тестировать какие либо изменения в алгоритме и структурах запросов достаточно сложно...
Есть ли возможность со стороны SAP делать выборку игнорируя оптимизации со стороны БД? Или хотя бы возможность как-нибудь их "искусственно" сбросить?

Автор:  pberezin [ Пт, мар 15 2019, 13:50 ]
Заголовок сообщения:  Re: Игнорирование буфера/кэша БД при select

так у вас видимо план запроса очень нехороший получается.
То что оно с буфера СУБД реально тянет, не улучшает оценку iocost/cpucost в плане запроса в принципе.

Автор:  Saperx [ Пт, мар 15 2019, 14:12 ]
Заголовок сообщения:  Re: Игнорирование буфера/кэша БД при select

Планы запроса в обоих случаях(на "холодную" и сразу после) абсолютно идентичные вплоть до всех костов.
Я может не правильно выразился. Сами выборки абсолютно идентичные. Просто хочется чтобы была возможность подряд запускать алгоритм в тесте, и чтобы каждый раз он работал будто это первый "холодный" запуск.

Этот запрос работает 2 секунды.
Code:
SELECT STATEMENT ( Estimated Costs = 10 204 , Estimated #Rows = 1 )

       3 FILTER
         Filter Predicates

           2 TABLE ACCESS BY INDEX ROWID CRM_JCDS
             ( Estim. Costs = 10 203 , Estim. #Rows = 1 )
             Estim. CPU-Costs = 354 019 764 Estim. IO-Costs = 10 189
             Filter Predicates

               1 INDEX RANGE SCAN CRM_JCDS~Z1
                 ( Estim. Costs = 91 , Estim. #Rows = 172 877 )
                 Search Columns: 2
                 Estim. CPU-Costs = 7 886 594 Estim. IO-Costs = 90
                 Access Predicates

Этот 200+
Code:
SELECT STATEMENT ( Estimated Costs = 10 204 , Estimated #Rows = 1 )

        3 FILTER
          Filter Predicates

            2 TABLE ACCESS BY INDEX ROWID CRM_JCDS
              ( Estim. Costs = 10 203 , Estim. #Rows = 1 )
              Estim. CPU-Costs = 354 019 764 Estim. IO-Costs = 10 189
              Filter Predicates

                1 INDEX RANGE SCAN CRM_JCDS~Z1
                  ( Estim. Costs = 91 , Estim. #Rows = 172 877 )
                  Search Columns: 2
                  Estim. CPU-Costs = 7 886 594 Estim. IO-Costs = 90
                  Access Predicates

Автор:  pberezin [ Пт, мар 15 2019, 14:36 ]
Заголовок сообщения:  Re: Игнорирование буфера/кэша БД при select

Цитата:
2 TABLE ACCESS BY INDEX ROWID CRM_JCDS
( Estim. Costs = 10 203 , Estim. #Rows = 1 )
Estim. CPU-Costs = 354 019 764 Estim. IO-Costs = 10 189


Сурово такто (и это в цикле - ресурсы я так понимаю тратятся в основном на пустое скакание туда-сюда по индексам).

Автор:  AntonSikidin [ Пт, мар 15 2019, 15:02 ]
Заголовок сообщения:  Re: Игнорирование буфера/кэша БД при select

кеш сбрасывать так

/$SYNC This resets all buffers of the application server
/$CUA This resets the CUA buffer of the application server
/$TAB This resets the TABLE buffers of the application server
/$NAM This resets the nametab buffer of the application server
/$DYNP - the screen buffer of the application server

Еще есть fm-ы но сходу не нашкл

Автор:  LKU [ Пт, мар 15 2019, 15:05 ]
Заголовок сообщения:  Re: Игнорирование буфера/кэша БД при select

AntonSikidin написал(а):
кеш сбрасывать так

/$SYNC This resets all buffers of the application server
/$CUA This resets the CUA buffer of the application server
/$TAB This resets the TABLE buffers of the application server
/$NAM This resets the nametab buffer of the application server
/$DYNP - the screen buffer of the application server

Еще есть fm-ы но сходу не нашкл


Это сброс кеша на сервере приложений SAP.
А Saperx спрашивает как сбросить кеш на уровне БД (я не знаю).

Автор:  pberezin [ Пт, мар 15 2019, 15:13 ]
Заголовок сообщения:  Re: Игнорирование буфера/кэша БД при select

както так наверное https://www.sql.ru/forum/actualutils.as ... sg=1517084

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

Автор:  pberezin [ Пт, мар 15 2019, 15:15 ]
Заголовок сообщения:  Re: Игнорирование буфера/кэша БД при select

Saperx написал(а):
Просто хочется чтобы была возможность подряд запускать алгоритм в тесте, и чтобы каждый раз он работал будто это первый "холодный" запуск.


Правильно понимаю, что предполагается оптимизация "методом научного тыка" ? :D

Автор:  ArmAnn [ Пт, мар 15 2019, 16:27 ]
Заголовок сообщения:  Re: Игнорирование буфера/кэша БД при select

Saperx написал(а):
Если же попытаться, повторно сделать трассировку, то в тестовой системе видимо уровне БД(т.к. настройка буферизации в se11 для таблицы не включена, да и запрос с джоином и через FAE), происходит буферизация и запрос отрабатывает оч. быстро(за пару секунд). При этом этот буффер может висеть часами в тесте(в проде уже через пару минут ситуация аналогична холодному запуску), в итоге приходится дожидаться когда БД посчитает буфер инвалидным и выгрузит таблицу. Только после этого есть возможность опять запустить выборку в тестовой системе и проверить примененные изменения.
Понятно, что при таком режиме тестировать какие либо изменения в алгоритме и структурах запросов достаточно сложно...
Есть ли возможность со стороны SAP делать выборку игнорируя оптимизации со стороны БД? Или хотя бы возможность как-нибудь их "искусственно" сбросить?

Можно 'забивать' буфер массивными выборками из других таблиц. Насколько выборки должны быть массивными - подбирается экспериментально.
Однако вам все таки нужно ориентироваться на план запроса, а не на замеры с секундомером.

Автор:  Kengur [ Пт, мар 15 2019, 18:07 ]
Заголовок сообщения:  Re: Игнорирование буфера/кэша БД при select

ArmAnn написал:
Saperx написал(а):
Если же попытаться, повторно сделать трассировку, то в тестовой системе видимо уровне БД(т.к. настройка буферизации в se11 для таблицы не включена, да и запрос с джоином и через FAE), происходит буферизация и запрос отрабатывает оч. быстро(за пару секунд). При этом этот буффер может висеть часами в тесте(в проде уже через пару минут ситуация аналогична холодному запуску), в итоге приходится дожидаться когда БД посчитает буфер инвалидным и выгрузит таблицу. Только после этого есть возможность опять запустить выборку в тестовой системе и проверить примененные изменения.
Понятно, что при таком режиме тестировать какие либо изменения в алгоритме и структурах запросов достаточно сложно...
Есть ли возможность со стороны SAP делать выборку игнорируя оптимизации со стороны БД? Или хотя бы возможность как-нибудь их "искусственно" сбросить?

Можно 'забивать' буфер массивными выборками из других таблиц. Насколько выборки должны быть массивными - подбирается экспериментально.
Однако вам все таки нужно ориентироваться на план запроса, а не на замеры с секундомером.

И параллельно еще ездить по дискам чтобы эмулировать продуктивную нагрузку на БД :mrgreen:

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

Автор:  Saperx [ Сб, мар 16 2019, 14:52 ]
Заголовок сообщения:  Re: Игнорирование буфера/кэша БД при select

pberezin написал:
Saperx написал(а):
Просто хочется чтобы была возможность подряд запускать алгоритм в тесте, и чтобы каждый раз он работал будто это первый "холодный" запуск.


Правильно понимаю, что предполагается оптимизация "методом научного тыка" ? :D

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

Касательно же плана запроса выше, то я пока не вижу явных мест для оптимизации
Code:
select hist~objnr, hist~stat, hist~udate
from crm_jcds
for all entries in lt_objects
WHERE  hist~objnr = lt_objects-objnr
    AND hist~stat IN ( 'E0001', 'E0002' )
    AND hist~udate IN so_date[]
    AND hist~inact = ''
    %_HINTS ORACLE '&MAX_IN_BLOCKING_FACTOR 1000&'.

Единственное что тут смущает сходу - выборка по пустому полю. Ну и отсортировать таблицу в FAE. В остальном же я хз.
Выбирать всю таблицу и крутить еще на своей стороне - тоже не выгодно, т.к. тут вся история по всем объектам, десятки миллионов записей.
Объектов может быть от 0 до десятков тысяч, но это "обычно" так бывает, а вообще вплоть до максимального значения, если пользователь не ограничит выбор на СЭ. Период - любой который захочет пользователь. Отчет - по сути аналитический за период, собирает статистику по куче параметров, считает новые параметры. Да, знаю, что есть же BW. Да и куча "но можно же...", но в данном случае - есть отчет, и его надо привести в чувство.
Структура таблицы
По полю udate в системе создан индекс Z1.

Автор:  LKU [ Вс, мар 17 2019, 09:25 ]
Заголовок сообщения:  Re: Игнорирование буфера/кэша БД при select

Максимальная скорость выборки будет, если индекс будет содержать все поля из ограничений и все выбираемые поля.
В этом случае план запроса будет содержать только обращение к индексу.
С учетом того, что udate может быть пустой, я бы предложил сделать такой индекс:
mandt
stat
inact
objnr
udate

Ну и поставить индексу compress 3.

Автор:  superbizon [ Пн, мар 18 2019, 09:42 ]
Заголовок сообщения:  Re: Игнорирование буфера/кэша БД при select

в хинте с 1000 не погорячились ли?
По идее раз два первых поля из первичного ключа в деле, то primary key должен использоваться, а не Z1.

Автор:  pberezin [ Пн, мар 18 2019, 16:31 ]
Заголовок сообщения:  Re: Игнорирование буфера/кэша БД при select

Code:
select hist~objnr, hist~stat, hist~udate
from crm_jcds
for all entries in lt_objects

Ну для начала - убедиться что конструкция select обёрнута в
Code:
IF lt_objects[] IS NOT INITIAL

Автор:  pberezin [ Пн, мар 18 2019, 17:36 ]
Заголовок сообщения:  Re: Игнорирование буфера/кэша БД при select

Цитата:
Период - любой который захочет пользователь. Отчет - по сути аналитический за период, собирает статистику по куче параметров, считает новые параметры

Тогда наверное надо проанализировать, за какие периоды чаще всего ищут, и какой % от общего числа объектов в таблице БД составляет lt_objects[] для данного периода. И под него оптимизировать.
А то и вообще жёстко ограничить минимальный набор ограничений/максимальный размер периода, который д.б. введён на сел.экране - в at sel-screen проверки повесить, не выпускающие пользователя на выполнение отчёта.

Цитата:
mandt
stat
inact
objnr
udate

самые неселективные поля в начале индекса (mandt который на продуктиве возможно 1 значение, inact понятно булево) - ораклиный оптимизатор будет такой индекс запросто ингорировать. Т.к. самым селективным он посчитает понятно objnr.
Т.е. objnr stat udate возможно будет лучше.
А м.б. даже выкинуть из where AND hist~inact = '' и заменить его зафильтровыванием IF NOT ( crm_jcds-inact = '' ). Тогда из плана запроса уйдёт Filter predicate, т.е. скорость выборки в БД ещё улучшится.

Страница 1 из 2 Часовой пояс: UTC + 3 часа
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/