Профилирование PL/SQL кода при помощи IDE PL/SQL Developer

    Проблематика и назначение:


    Периодически Oracle разработчики сталкиваются с проблемой производительности PL/SQL кода. Возникают проблемы с тем, чтобы найти место pl/sql кода, в котором возникают проблемы.

    Обычно профилирование pl/sql кода используется, когда необходимо определить проблему производительности в очень большом методе, либо когда у метода много внутренних зависимостей с большим количеством логики, а также нет понимание в каком месте метод код тормозит.

    Методы решения проблемы:


    В решение проблем с производительность в БД Oracle нам помогут:

    • PL/SQL Developer — Популярное IDE для Oracle разработчиков.
    • DBMS_PROFILE — Oracle пакет для профилирования (не будет рассматриваться в рамках данной статьи, т.к. информации достаточно на просторах интернета).


    Метод(процедура) для профилирования:


    В рамках данной статьи покажу всего лишь подход к профилированию, поэтому метод, который мы будем профилировать будет не большим.

    Создадим метод для профилирования:

    create or replace procedure check_cycle_performance(p_cycle_size in number) is
        c_method_error         constant number := -20000;
        c_method_error_message constant varchar2(4000) := 'Cycle size should be > 0';
        l_power_value number;
        l_dual_value  number;
    begin
        if p_cycle_size > 0 then
            --Cycle with power calculation
            for i in 1 .. p_cycle_size
            loop
                l_power_value := power(i, 2);
            end loop;
            --Cycle with switching context(sql-pl/sql)
            for i in 1 .. p_cycle_size
            loop
                select i into l_dual_value from dual;
            end loop;
        else
            raise_application_error(c_method_error, c_method_error_message);
        end if;
    end check_cycle_performance;

    Профилирование через IDE PL/SQL Developer:


    В pl/sql Developer запускаем Test Window:


    Рисунок 1 — Запуск Test Window

    В тестовом окне наберём код для запуска метода check_cycle_performance, заполним входную переменную l_cycle_size и нажмем кнопку для запуска профилирования:


    Рисунок 2 — Запуск профилирования в PL/SQL Developer

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

    Далее по F8 запускаем метод, после его выполнения переходим во вкладку Profiler:


    Рисунок 3 — Окно профайлера в PL/SQL.

    Из рисунка 3 видно, что основная проблема по производительности состоит в строке 16.

    Не трудно понять, что основная проблема производительности кроется в переключениях контекста SQL — PL/SQL.

    При этом возведение в степень: строка 11, занимает гораздо меньше времени.

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

    Подробнее
    Реклама

    Комментарии 9

      0
      Спасибо! Много лет пользуюсь PL/SQL Developer, а о такой возможности узнал только сейчас.
        0
        Отличная статья, спасибо! Ждем продолжения.
          0
          А это профилирование изолированно от реальных данных?
            0
            Конкретно этот пример был показан для выявления проблем на тестовой/разработческой среде. Можно конкретнее в чем заключается вопрос?
              0
              Ну то есть, если у меня уже есть написанные процедуры и я хочу найти в них слабое место. Выполнение профилирования отразится на таблицах, которые учавствуют в процедуре? Или это будет сделано без коммита данных?
                0
                Это зависит от того как ты сам управляешь транзакцией: если у тебя где-либо в коде стоит фиксация транзакции, то данные естественно зафиксируются, если нет — то нет. Если нет фиксации транзакций, то можешь в тестовом окне(рисунок 2) поставить rollback.
            0
            В принципе, PL/SQL Developer использует тот же DBMS_PROFILER (кстати, есть еще иерархический профайлер ).
            Для большей автоматизации иногда удобнее пользоваться своими запросами к этим же таблицам. Вот рыба для них:
            select r.runid
                  ,r.related_run
                  ,r.run_owner
                  ,r.run_date
                  ,r.run_comment
                  ,r.run_total_time
                  ,r.run_system_info
                  ,r.run_comment1
                  ,u.unit_number
                  ,u.unit_type
                  ,u.unit_owner
                  ,u.unit_name
                  ,d.line#
                  ,s.TEXT
                  ,u.total_time
                  ,d.total_occur
                  ,d.total_time
                  ,d.min_time
                  ,d.max_time      
            from plsql_profiler_runs r
                 join plsql_profiler_data d
                      on  r.runid = d.runid
                 join plsql_profiler_units u
                      on  d.runid = u.runid
                      and d.unit_number = u.unit_number
                 left join all_source s
                      on  u.unit_owner = s.OWNER
                      and u.unit_name  = s.NAME 
                      and u.unit_type  = s.TYPE 
                      and d.line#      = s.LINE
            where 1=1
            --  and r.run_owner = user -- запуски от текущей юзера
            --  and r.runid = (select max(runid) from plsql_profiler_runs where run_owner=user) -- последний запуск
            order by r.runid,r.related_run,u.unit_number,d.line#;
            
              0
              В нем (PLSQL Dev) удобно еще дебажить.
              Спасибо за статью.
                0
                Хотелось бы добавить, что двойной клик по строке в профайлере в PL/SQL Dev переводит к соответствующей строке исходного кода. Это полезно, когда в тестовом окне вызываются пакетные функции. Разумеется, пакет не должен быть скомпилирован нативно.

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

                Самое читаемое