2012-03-11 13 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; 

czy to jedno:plsql - otrzymasz pierwszy wiersz - który z nich jest lepszy?

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

Zarówno powyżej zrobić podobny wynik, ale muszę wiedzieć o który z nich jest bardziej wydajny!

Odpowiedz

7

To jest Tom Kyte jest mantra:

Należy to zrobić w pojedynczej instrukcji SQL, jeśli w ogóle możliwe.
Jeśli nie możesz tego zrobić w pojedynczej instrukcji SQL, zrób to w PL/SQL.
Jeśli nie możesz tego zrobić w PL/SQL, spróbuj procedury składowanej Java.
Jeśli nie możesz tego zrobić w Javie, zrób to w zewnętrznej procedurze C.
Jeśli nie można tego zrobić w rutynę zewnętrznego C, warto poważnie zastanowić się, dlaczego to trzeba to zrobić ...

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

3

Najprostszym sposobem, aby dowiedzieć się, w tym przypadku jest przetestuj swoje zapytania.

Pamiętaj, aby przetestować to samodzielnie, indeksy i dane w tabeli mogą dawać różne wyniki w tabeli.

Bez indeksu, wygląda na to, że to lepsze podejście przy użyciu funkcji analitycznej DENSE_RANK:

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

Użyłem następujący kod do testowania czasu zużywanego przez zapytań (wykonać ten blok kilka razy, wyniki mogą być różne)

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; 

Wyniki:

  1. kursorem, rozróżniając pierwszego rzędu:
    2.241 s

  2. poprzez wysłanie z ROWNUM:
    1.483 s

  3. Korzystanie DENSE_RANK:
    1.168 s

+0

+1 za bardzo dobrą analizę ze statystyką –

Powiązane problemy