измерить время SQL-оператора в процедуре в plsql - PullRequest
10 голосов
/ 20 января 2012

Я должен написать процедуру, которая сохранит время выполнения любого SQL-оператора в таблице.

Процедура вызывается по exec measuresqltime('sql statement as string');

Моя идея такова:

  --declarations 
  timestart NUMBER;
  BEGIN 
    dbms_output.enable; 
    timestart:=dbms_utility.get_time(); 
    EXECUTE IMMEDIATE sql
    COMMIT; 
    dbms_output.put_line(dbms_utility.get_time()-timestart); 
    -- save time

Но это не сработало для меня для SELECT *... предложения. (Я думаю, что sql нужен INTO-заказ)

Есть ли способ выполнить какие-либо sql-заявления в процедуре?

Ответы [ 4 ]

15 голосов
/ 20 января 2012

Если ваш оператор SQL является SELECT, вам нужно извлечь из курсора, чтобы иметь значимый показатель его времени выполнения.

Если вы не извлекаете данные из курсора, вы измеряете только время, проведенное в фазах "синтаксический анализ" и "выполнение", тогда как большая часть работы обычно выполняется в фазе "выборка" для операторов SELECT.

Вы не сможете получить с помощью EXECUTE IMMEDIATE или OPEN cursor FOR 'string', если не знаете количество столбцов, которое будет иметь фактический оператор.Вам придется использовать динамический пакет SQL DBMS_SQL, если число / тип столбцов SELECT неизвестен.

Вот пример:

SQL> CREATE OR REPLACE PROCEDURE demo(p_sql IN VARCHAR2) AS
  2     l_cursor  INTEGER;
  3     l_dummy   NUMBER;
  4     timestart NUMBER;
  5  BEGIN
  6     dbms_output.enable;
  7     timestart := dbms_utility.get_time();
  8     l_cursor  := dbms_sql.open_cursor;
  9     dbms_sql.parse(l_cursor, p_sql, dbms_sql.native);
 10     l_dummy := dbms_sql.execute(l_cursor);
 11     LOOP
 12        EXIT WHEN dbms_sql.fetch_rows(l_cursor) <= 0;
 13     END LOOP;
 14     dbms_sql.close_cursor(l_cursor);
 15     dbms_output.put_line(dbms_utility.get_time() - timestart);
 16  END;
 17  /

Procedure created.

SQL> exec demo('SELECT * FROM dual CONNECT BY LEVEL <= 1e6');
744

PL/SQL procedure successfully completed.

Обратите внимание, что это будет измерять время, необходимое для извлечения до последней строки SELECT.

4 голосов
/ 16 апреля 2015

завершение devosJava ответил ... избегать его на рассвете; P

PROCEDURE MY_PROCEDURE IS
  timeStart  TIMESTAMP;
  timeEnd    TIMESTAMP;
  timeSecond NUMBER
BEGIN
  timeStart  := SYSTIMESTAMP;

  -- YOUR CODE HERE

  timeEnd    := SYSTIMESTAMP;
  timeSecond :=((extract(hour from timeEnd)*3600)+(extract(minute from timeEnd)*60)+extract(second from timeEnd))-((extract(hour from timeStart)*3600)+(extract(minute from timeStart)*60)+extract(second from timeStart));
  dbms_output.put_line('finished: '||timeSecond||' seconds');
END MY_PROC;
1 голос
/ 30 мая 2013

Чтобы рассчитать продолжительность времени выполнения

PROCEDURE MY_PROCEDURE IS
  timeStart  TIMESTAMP;
  timeEnd    TIMESTAMP;
BEGIN
  timeStart  := SYSTIMESTAMP;

  -- YOUR CODE HERE

  timeEnd    := SYSTIMESTAMP;

  INSERT INTO PROC_RUNTIMES (PROC_NAME, START_TIME, END_TIME)
    VALUES ('MY_PROCEDURE ', timeStart  , timeEnd    );
END MY_PROC;
0 голосов
/ 07 декабря 2015

INSERT INTO PROC_RUNTIMES (PROC_NAME, START_TIME, END_TIME) VALUES ('PROC_NAME', TO_CHAR (SYSDATE, 'DD / MM / YYYY HH24: MI: SS'), NULL);

Ваш запрос здесь;

INSERT INTO PROC_RUNTIMES (PROC_NAME, START_TIME, END_TIME) ЗНАЧЕНИЯ ('PROC_NAME', NULL, TO_CHAR (SYSDATE, 'DD / MM / YYYY HH24: MI: SS'));

)
...