2012-01-20 35 views
5

Tôi phải viết một thủ tục lưu thời gian thực hiện của bất kỳ câu lệnh sql nào trong một bảng.đo thời gian của một câu lệnh sql trong một thủ tục trong plsql

Thủ tục được gọi bởi exec measuresqltime('sql statement as string');

Ý tưởng của tôi là như thế này:

--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 

Nhưng nó không làm việc cho tôi một khoản SELECT *.... (Tôi nghĩ sql cần một đơn đặt hàng INTO)

Có cách nào để thực hiện bất kỳ câu lệnh sql nào trong quy trình không?

Trả lời

13

Nếu câu lệnh SQL của bạn là một SELECT, bạn cần tìm nạp từ con trỏ để có một thước đo có ý nghĩa về thời gian thực hiện của nó.

Nếu bạn không tìm nạp từ con trỏ, bạn chỉ đo thời gian trong giai đoạn "phân tích cú pháp" và "thực thi", trong khi phần lớn công việc thường được thực hiện trong giai đoạn "tìm nạp" cho câu lệnh SELECT.

Bạn sẽ không thể tìm nạp với EXECUTE IMMEDIATE hoặc OPEN cursor FOR 'string' nếu bạn không biết số lượng cột mà tuyên bố thực tế sẽ có. Bạn sẽ phải sử dụng gói SQL động DBMS_SQL nếu số lượng/loại cột của SELECT không xác định.

Dưới đây là một ví dụ:

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. 

Lưu ý rằng điều này sẽ đo thời gian cần thiết để lấy đến dòng cuối cùng của SELECT.

+0

hey, có vẻ tuyệt vời :) nhưng nó chỉ hoạt động fpr chọn báo cáo phải không? Có một tùy chọn o chạy xóa hoặc chèn-báo cáo? – sheepy

+0

@sheepy: Bạn không thể tìm nạp con trỏ DML (INSERT/UPDATE ...) để dòng 12 sẽ tăng lỗi trong trường hợp đó. Nắm bắt ngoại lệ và thủ tục sẽ làm việc cho cả các truy vấn DML và SELECT. –

1

Để tính toán thời gian cho một thời gian thực hiện

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

hoàn devosJava trả lời ... tránh sử dụng nó vào lúc bình minh; 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; 
+2

'timeSecond: = trích xuất (thứ hai từ timeEnd - timeStart);' – Roland

0

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

Truy vấn của bạn tại đây;

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

Các vấn đề liên quan