测量plsql过程中sql语句的时间
Posted
技术标签:
【中文标题】测量plsql过程中sql语句的时间【英文标题】:measure time of an sql statement in a procedure in plsql 【发布时间】:2012-02-14 22:13:58 【问题描述】:我必须编写一个程序来节省表中任何 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-order)
有没有办法在过程中执行任何 sql 语句?
【问题讨论】:
【参考方案1】:如果您的 SQL 语句是 SELECT,您需要从游标中获取数据,以便对其执行时间进行有意义的测量。
如果您不从游标中获取,则仅测量在“解析”和“执行”阶段花费的时间,而大部分工作通常在 SELECT 语句的“获取”阶段完成。
如果您不知道实际语句的列数,您将无法使用EXECUTE IMMEDIATE
或OPEN cursor FOR 'string'
获取。如果 SELECT 的列数/类型未知,则必须使用动态 SQL 包 DBMS_SQL
。
这是一个例子:
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 的最后一行所需的时间。
【讨论】:
嘿,这看起来很棒:) 但它只适用于 fpr select 语句,不是吗?是否有运行删除或插入语句的选项? @sheepy:您无法获取 DML 游标(INSERT/UPDATE...),因此第 12 行将在这种情况下引发错误。捕获异常,该过程将适用于 DML 和 SELECT 查询。 dbms_utility.get_time 不可信,您应该使用 systimestamp 代替,请参阅asktom.oracle.com/pls/asktom/… @Superdooperhero 这根本不是 Tom Kyte 的建议!他建议用SYSTIMESTAMP
替换SYSDATE
以获得更高的精度。他仍然使用dbms_utility.get_time
in his suggested code :)【参考方案2】:
计算执行时间的持续时间
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;
【讨论】:
【参考方案3】:完成 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;
【讨论】:
timeSecond := extract(second from timeEnd - timeStart);
【参考方案4】:
INSERT INTO PROC_RUNTIMES(PROC_NAME,START_TIME,END_TIME) 值('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'));
【讨论】:
以上是关于测量plsql过程中sql语句的时间的主要内容,如果未能解决你的问题,请参考以下文章
plsqldeveloper如何检索sql语句在哪些存储过程