PLSQL_性能优化系列07_Oracle Parse Bind Variables解析绑定变量
2014-09-25 Created By BaoXinjian
一、綁定變量用法和使用場合
使用綁定變量的重要性:如果不使用綁定變量而使用常量,會導致大量硬解析。由于硬解析的種種危害,不使用綁定變量往往是影響oracle性能和擴展性的最大問題
以下為一些錯誤寫法和正確寫法的例子
1. PLSQL中普通查詢
(1). 錯誤寫法
SELECT * FROM emp WHERE empno=123;
(2). 正確寫法(未使用綁定變量)
Empno:=123;
SEELCT* FROM emp WHERE empno=:empno;
2. PLSQL中在使用動態SQL
(1). 錯誤的寫法
sqlstr:= 'select * from emp where empno='||empno;Execute immediate for sqlstr;
EXECUTE IMMEDIATE FOR sqlstr;
(2). 正確的寫法
sqlstr:= 'select * from ?empno='||empno;?
EXECUTE IMMEDIATE FOR sqlstr;?
因為前者使用字符串拼接較容易,很多人會這么用。
?
二、如何判斷和定位系統中未使用綁定變量的語句
在awr的load?profile部分,有個Hard?parses指標,表示每秒的hard?parse。
另外在Instance Efficiency?Percentages部分,Soft?Parse?%這個指標反映的是硬解析占所有解析的比例。
這兩個指標一個是絕對值,一個是相對值。每秒hard?parse指標應該比較低,而soft?parse%應該較高(有人說應大于95%)。
具體合理指標和系統大小、業務量、業務類型都有關,可以參考的是siebel系統中這兩個值是11和98%。如果這兩個指標超出合理范圍,則說明硬解析太多,應引起重視,分析產生的原因。
?
例子: 未使用綁定變量是導致硬解析的最常見原因,那么如何找出這些SQL
Step1. 可以用以下語句找到哪些SQL:
SELECT substr(sql_text,1,50) "SQL", count(*), sum(executions) "TotExecs" FROM v$sqlarea WHERE executions < 5 GROUP BY substr(sql_text,1,50) HAVING count(*)> 30 ORDER BY 2;?
Step2. 用以下語句找到運行這些sql的用戶和模塊
SELECT service, module, parsing_schema_name, sql_text FROM v$sql where sql_text LIKE 'select rownum as ….id%’;?
?
三、減少解析,包括硬解析和軟解析
1. 問題由來
Sql優化(六) 中我們介紹了soft parse/hard parse的概念,以及通過使用綁定變量減少hard parse的技術。
在生產環境中,我們發現soft parse太多也會引起性能問題,例如較高的library cachelatch contention等待,盡管soft parse相比hard parse,性能開銷已經小很多。
最高境界是no parse;減少parse的訣竅是oracle的cursor。
2. Sql的執行過程和parse分類,oracle運行sql時,過程如下:
(1). Sql cursor是否open?如果是則跳到5) 這種情況即為no parse,為方便比較,我們也作為parse的一種類型
(2). cursor是否在session cache中(pga),如果存在,則跳到5)這種情況oracle專家tom稱其softer soft parse
(3). 進行syntax check和 semantic check,然后在shared pool的hash表中尋找,如果匹配到則跳到step 5),這稱為soft parse
(4). 如果匹配失敗,則需要security-check,optimize,生成query plan等等,這稱為hard parse(硬解析),可以想像成源程序先編譯后運行。
(5). execute
?
3. 各類parse的開銷
我們分別比較上面幾種parse類型的開銷
可見hard parse開銷最大,soft parse其次。Parse引起的latch contention不僅影響程序運行速度,而且影響程序的擴展性(scalable)
?
4.? 如何減少hard parse
(1). 使用綁定變量
這是編程方法中最影響性能的因素之一,具體做法由其他文章介紹
(2). 編程規范,良好的編程習慣
編程規范可以規定表名、關鍵字是否用大寫,空格怎么用等等,所有程序員遵循統一的規范。
舉個例子說明其意義,在數據庫中cursor_sharing缺省值為exact,這意味著oracle對sql進行匹配時,以下兩句是不匹配的,第二句會引起hard parse
select count(*) from test_table where tracking_id=1234567688;
select count(*) from TEST_TABLE where tracking_id=1234567688;
當然第一點遠比第二點重要,大家可以想象。
?
?
5. 如何減少soft parse
即no parse和softer soft parse,訣竅是oracle 的cursor,具體來說有兩種方法
Step1. Skip parse
在子程序中,跳過parse,采用以下寫法:
if (firsttime)
parse
end if
bind
execute
而不要這么寫,因為每次調用都進行了parse
parse
bind
execute
close
例如在java中,通過prepareStatement,每個session對該sql prepare一次,而不是每次調用都prepare一次。
2. PLSQL自動cache cursor
在PLSQL中,所有static sql都是被cache的,重復調用時不會進行soft parse。注意動態sql除外。
declarei number;j number;k number; begini:=1;k:=12345678;while i<=10000 loopselect count(*) into j from test_table where tracking_id=k;i:=i+1;end loop; end; /?
3. SESSION_CACHED_CURSORS參數
如果該參數非0,則在sqlplus中,當同一sql進行了三次soft parse,oracle會將cursor 移到cache中,第4次調用時則不需soft parse,但仍會注冊為parse,
parse count (total)仍會增加,同時session cursor cache hits也會增加。
該參數影響以下工具:
- 1)Sqlplus
- 2)Plsql中的native dynamic sql
- 3)Java中不好的寫法,如不進行prepare而直接execute 的sql
- 4)Oracle產生的recursive sql
各個版本的區別:
Oracle9i中session_cached_cursors默認為0,oracle 10g中似乎為20,ora11g默認為50,因此在oracle9i中,如果要使用此特性,需要修改默認值。
另外一點要注意的是,soft parse表示一個session進行了hard pasre之后,只要仍在shared pool中,所以其他session都不需再hard parse。
而session_cached_cursor,是針對同一session而言的。因此如果一個程序頻繁logon/logoff,是無法用到這一特性的。
?
Thanks and Regards
轉載于:https://www.cnblogs.com/eastsea/p/3981054.html
總結
以上是生活随笔為你收集整理的PLSQL_性能优化系列07_Oracle Parse Bind Variables解析绑定变量的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: valueOf()、toString()
- 下一篇: js中的墙头草---this