2012-04-20 85 views
1

我們已經一個PreparedStatement它需要做的分貝多個操作,因此所有這些SQL語句被封閉在一個BEGIN-END塊類似甲骨文硬解析

BEGIN 
DELETE FROM...WHERE A=?.. 
UPDATE TABLE...WHERE B=?.. 
END; 

但許多評論說,這將導致一個硬解析。根據我的理解,硬解析是當在共享池中找不到sql時,那麼語法,執行計劃......一切都需要再次計算,但這裏不應該將Oracle視爲單獨的sql語句。 我怎樣才能找出oracle會在給定的sql語句上做一個硬解析?

回答

7

綁定變量在PL/SQL塊很好的工作,因爲他們在SQL語句做。

您可以通過在循環中運行簡單語句來測試此操作,然後查看v$sesstat中的分析計數。

創建一個簡單的表用於插入和刪除。獲取初始分析計數。

create table test1(a number); 

--Flush the pool, or else this test won't be repeatable. 
alter system flush shared_pool; 

select value, name 
from v$sesstat natural join v$statname 
where sid = sys_context('userenv', 'sid') 
    and name in ('parse count (total)', 'parse count (hard)'); 

47 parse count (total) 
5 parse count (hard) 

這就是硬解析的樣子:

begin 
    for i in 1 .. 10000 loop 
     execute immediate 'insert into test1 values('||i||')'; 
    end loop; 
    commit; 
end; 
/

select value, name 
from v$sesstat natural join v$statname 
where sid = sys_context('userenv', 'sid') 
    and name in ('parse count (total)', 'parse count (hard)'); 

10072 parse count (total) 
10007 parse count (hard) 

與綁定變量並不總是硬解析PL/SQL塊。請注意,分析計數是累積的,並且在這裏僅略有增加。

begin 
    for i in 1 .. 10000 loop 
     execute immediate 
     'begin 
      delete from test1 where a = :i; 
     end;' 
     using i; 
    end loop; 
    commit; 
end; 
/

select value, name 
from v$sesstat natural join v$statname 
where sid = sys_context('userenv', 'sid') 
    and name in ('parse count (total)', 'parse count (hard)'); 

10106 parse count (total) 
10019 parse count (hard) 
3

跟蹤您的會話執行代碼。運行tkprof並檢查解析數字。

你使用綁定變量還是使用文字?

建議使用綁定變量,因爲當您使用 - 更改 - 文字時,這是導致解析發生的因素之一。更改文字確實會降低您的表現,使用綁定。

這裏是一個不錯的視頻解釋和顯示會發生什麼:OLTP Performance - The Trouble with Parsing