Как профилировать сквозную производительность хранимой процедуры Oracle - PullRequest
4 голосов
/ 05 октября 2011

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

Есть ли простой простой способ сделать это очень простое задание?

Конечно, отчет о том, что происходит во время выполнения хранимой процедуры и сколько времени хранимой процедуры тратится на выполнение каждой задачи (insert, plsql)манипуляции со строками и т. д.) было бы бонусом, но я действительно просто хочу что-то простое и удобное в использовании.(И бесплатно)

Ответы [ 3 ]

6 голосов
/ 05 октября 2011

Если вы используете Oracle 11g, вы должны взглянуть на иерархический профилировщик, DBMS_HPROF.Это инструмент, который даст вам истекшее время для всех узлов в программе PL / SQL.Как следует из названия, это особенно полезно для исследования программ, которые вызывают программы, которые вызывают программы.Он также определяет время для операторов SQL, отличное от вызовов функций. Узнать больше .

Он является частью стандартного развертывания 11g и, следовательно, является бесплатным.Ну, как только вы заплатили за свою лицензию, она становится бесплатной :)

По умолчанию права на пакет DBMS_HPROF не предоставляются никому.Итак, вам нужно, чтобы кто-нибудь с доступом SYSDBA увидел вас правильно.Анализ также требует создания некоторых таблиц.Ни одна из этих вещей не должна быть проблемой, но я знаю, что иногда они есть.


Увы, у вас более ранняя версия.Так что остается только DBMS_PROFILER, который существует с 9i.Это в основном хорошо работает для одной программы.Его главный недостаток заключается в том, что мы можем использовать его только в тех программах, для которых у нас есть привилегия CREATE (т. Е. Только в программах в нашей схеме, если у нас нет привилегии CREATE ANY PROCEDURE, что обычно означает быть администратором БД).Кроме того, для профилирования встроенных операторов SQL нам необходимо использовать пакет DBMS_TRACE. Узнайте больше.

3 голосов
/ 05 октября 2011

SIMPLEST, CHEAPEST OPTION Вы можете записывать события в таблицу «отладки» и проверять продолжительность между журналами, как, например, для ex.Записать событие перед вставкой в ​​таблицу a с отметкой времени a в таблицу отладки.Записывайте событие после вставки в таблицу a с отметкой времени b в таблицу отладки.

Это занимает немного времени, если ваша хранимая процедура занимает больше 5 строк, но тем не менее она вам поможет.Также реализуйте флаг отладки, поэтому, когда вам нужно записать метки времени, установите флаг в верхней части процедуры в значение true, а затем повторно скомпилируйте его.При выполнении хранимой процедуры она пойдет и зарегистрирует все ваши события, после завершения отладки установите флаг в false и перекомпилируйте.

0 голосов
/ 29 мая 2019

Если вы хотите написать собственный промежуток времени в ваших программах на PL / SQL, ниже приведен мой шаблон код для этого. Кроме того, это не требует помощи вашего администратора БД. Мои администраторы часто не хотят давать мне больше доступа к большему количеству вещей. И я ненавижу ждать, пока они действительно предоставят мне доступ.

/* This procedure is simply an example of parsing out an Elapsed time into their individual time parts */
/*   In other words it provides to the user the elapsed time in hours : minutes : seconds . milliseconds */

DECLARE

  G_START_TIME1     NUMBER        := DBMS_UTILITY.GET_TIME;
  G_START_TIME2     NUMBER        := DBMS_UTILITY.GET_TIME;
  vG_ELAPSED_TIME   VARCHAR2(200);

  /* Variables below are used for storing Elapsed time. */
  RETVAL           NUMBER;
  hourss            NUMBER;
  minutess          NUMBER;
  secondss          NUMBER;
  millisecondss     NUMBER;
    n_hrs         NUMBER := 360000;
    n_mins        NUMBER := 6000;
    n_secs        NUMBER := 100;
    n_sixty       NUMBER := 60;
    n_thirty      NUMBER := 30;
    n_ten         NUMBER := 10;

  v_PrintTime     VARCHAR2(200);


  /* The procedure below is simply used to simulate the passage of time */
  PROCEDURE waste_time(pn_Seconds NUMBER) IS

  n_CentiSeconds  NUMBER  :=  pn_Seconds * 100;
  n_ProgramStart  NUMBER  := DBMS_UTILITY.GET_TIME; /* dbms_utility_get_time returns times in hundreds of a second */

  BEGIN
    WHILE DBMS_UTILITY.GET_TIME < n_ProgramStart + n_CentiSeconds
    LOOP
      null;
    END LOOP;
  END waste_time;

BEGIN

  G_START_TIME1   :=    -2019618227; --dbms_utility.get_time;

  --waste_time(1);
  --dbms_output.put_line('1 Second Wasted'|| chr(10));

  G_START_TIME2   :=    G_START_TIME1 + 366110; ---2019619227; --dbms_utility.get_time;

  dbms_output.put_line('Start_time: '||G_START_TIME1);
  dbms_output.put_line('End_time:   '||G_START_TIME2||chr(10));

  vG_ELAPSED_TIME :=  G_START_TIME2 - G_START_TIME1;
  millisecondss   :=  vG_ELAPSED_TIME * n_ten;
  secondss        :=  vG_ELAPSED_TIME / n_secs;
  minutess        :=  vG_ELAPSED_TIME / n_mins;
  hourss          :=  vG_ELAPSED_TIME / n_hrs;

  dbms_output.put_line('Total Time: '||millisecondss ||' Milliseconds');
  dbms_output.put_line('Total Time: '||vG_ELAPSED_TIME ||' Centiseconds');
  dbms_output.put_line('Total Time: '||secondss ||' Seconds');
  dbms_output.put_line('Total Time: '||minutess ||' Minutes');
  dbms_output.put_line('Total Time: '||hourss ||' Hours');

  millisecondss   :=  mod(vG_ELAPSED_TIME * n_ten, 1000);            /* Milliseconds into Seconds.  Returns left over millisedonds */
  secondss        :=  trunc(mod(vG_ELAPSED_TIME / n_secs, n_sixty)); /* Seconds into hours.  Returns how many seconds are left over */
  minutess        :=  trunc(mod(vG_ELAPSED_TIME / n_mins, n_sixty)); /* Seconds into hours.  Returns how many seconds are left over */
  hourss          :=  trunc(vG_ELAPSED_TIME / n_hrs);                /* Spit out hours only using just trunc here.  Since we don't need to build up Days we can leave this as is */

  v_PrintTime     :=  hourss ||':'|| minutess ||':'|| secondss ||'.'|| millisecondss;

  dbms_output.put_line(chr(10) ||'Elapsed Time: '|| v_PrintTime);


END;
...