Если ваш оператор 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.