2012-03-11 49 views
5
LV_id number; 
Cursor CR_test Is 
    select t.id 
    from table1 t 
    where t.foo = p_foo 
    order by t.creation_date; 

Open CR_test; 
Fetch CR_test 
Into LV_id; 
Close CR_test; 

或者這一個:plsql - 獲得第一行 - 哪一個更好?

select x.id 
from(select t.id 
    from table1 t 
    where t.foo=p_foo 
    order by t.creation_date) x 
where rownum = 1 

兩個以上做類似的結果,但我需要知道關於哪一個更高效!

回答

7

這是湯姆凱特的口頭禪:

你應該做的,如果在所有可能的一個SQL語句。
如果您無法在單個SQL語句中執行此操作,請在PL/SQL中執行此操作。
如果您不能在PL/SQL中執行此操作,請嘗試使用Java存儲過程。
如果你不能用Java來完成,那麼在C外部程序中執行它。
如果你不能在C外部例程做到這一點,你可能要認真思考一下爲什麼它是你需要做...

http://tkyte.blogspot.com/2006/10/slow-by-slow.html

3

最簡單的方法來找出在這種情況下是測試你的查詢。

請務必自己測試,表中的索引和數據可能會與您的表產生不同的結果。

沒有任何指標,它看起來像有使用分析功能DENSE_RANK一個更好的辦法:

SELECT MIN(id) KEEP (DENSE_RANK FIRST ORDER BY creation_date) 
INTO lv_id 
FROM table1 
WHERE foo = p_foo; 

我用下面的代碼來測試你的查詢所消耗的時間(執行此塊數次,結果可能有所不同):

DECLARE 
    p_foo table1.foo%TYPE := 'A'; 
    lv_id table1.id%TYPE; 
    t  TIMESTAMP := SYSTIMESTAMP; 
BEGIN 
    FOR i IN 1 .. 100 LOOP 
    -- Query here 
    END LOOP; 
    dbms_output.put_line(SYSTIMESTAMP - t); 
END; 

結果:

  1. 使用遊標,獲取第一行:
    2.241小號

  2. 使用查詢與ROWNUM
    1.483小號

  3. 使用DENSE_RANK
    1.168 s

+0

+1非常適合靜態分析 – 2012-03-11 11:18:35