日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

BIND_MISMATCH导致过多VERSION COUNT的问题

發布時間:2024/9/5 编程问答 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BIND_MISMATCH导致过多VERSION COUNT的问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

并不是用了綁定變量就一定都會游標共享,下面我們介紹的就是一種例子。BIND_MISMATCH導致VERSION COUNT過多的原因解釋:

This is due to the bind buffer mismatch of the current child cursor. If oracle is unable to bind the current value to the existing child cursors bind buffer,?
Oracle upgrades the existing child cursor with a high bind buffer. This will force the query to do a hard parse and a new child cursor will be created.

對于綁定變量,ORACLE根據變量長度進行了分級,對于VARCHAR2類型共有如下4級:

第一級: 1-32
第二級: 33-128
第三級: 129-2000
第四級: 2000+

Oracle在進行bind graduation的時候,使用的是綁定變量的聲明類型長度。對于定義的變量在同一級可以共享游標,否則會生成子游標,如下:

SQL> desc t
?名稱 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?是否為空? 類型
?----------------------------------------- -------- ----------------------------
?X ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?VARCHAR2(30)

SQL>?variable v_x varchar2(32)

SQL> exec :v_x:='a';


PL/SQL 過程已成功完成。

SQL> select * from t where x=:v_x;

未選定行

SQL> ?select sql_id,child_number,executions from v$sql where sql_text='select * from t where x=:v_x';

SQL_ID ? ? ? ?CHILD_NUMBER EXECUTIONS
------------- ------------ ----------
1pqg8dpwthcp3 ? ? ? ? ? ?1 ? ? ? ? ?1

SQL>?variable v_x varchar2(33)
SQL> exec :v_x:='a';

PL/SQL 過程已成功完成。

SQL> select * from t where x=:v_x;

未選定行

SQL> select sql_id,child_number,executions from v$sql where sql_text='select * from t where x=:v_x';

SQL_ID ? ? ? ?CHILD_NUMBER EXECUTIONS
------------- ------------ ----------
1pqg8dpwthcp3 ? ? ? ? ? ?1 ? ? ? ? ?1
1pqg8dpwthcp3 ? ? ? ? ? ?2 ? ? ? ? ?1

SQL> select ?child_number,bind_mismatch from v$sql_shared_cursor where sql_id='1pqg8dpwthcp3';

CHILD_NUMBER B
------------ -
? ? ? ? ? ?1 N
? ? ? ? ? ?2 Y

SQL>?variable v_x varchar2(129)
SQL> exec :v_x:='a';

PL/SQL 過程已成功完成。

SQL> select * from t where x=:v_x;

未選定行

SQL> select sql_id,child_number,executions from v$sql where sql_text='select * from t where x=:v_x';

SQL_ID ? ? ? ?CHILD_NUMBER EXECUTIONS
------------- ------------ ----------
1pqg8dpwthcp3 ? ? ? ? ? ?1 ? ? ? ? ? 1
1pqg8dpwthcp3 ? ? ? ? ? ?2 ? ? ? ? ?1
1pqg8dpwthcp3 ? ? ? ? ? ?3 ? ? ? ? ?1

SQL> ?select ?child_number,bind_mismatch from v$sql_shared_cursor where sql_id='1pqg8dpwthcp3';

CHILD_NUMBER B
------------ -
? ? ? ? ? ?1 N
? ? ? ? ? ?2 Y
? ? ? ? ? ?3 Y


SQL>?variable v_x varchar2(2001)
SQL> exec :v_x:='a';

PL/SQL 過程已成功完成。

SQL> select * from t where x=:v_x;

未選定行

SQL> select sql_id,child_number,executions from v$sql where sql_text='select * from t where x=:v_x';

SQL_ID ? ? ? ?CHILD_NUMBER EXECUTIONS
------------- ------------ ----------
1pqg8dpwthcp3 ? ? ? ? ? ?1 ? ? ? ? ?1
1pqg8dpwthcp3 ? ? ? ? ? ?2 ? ? ? ? ?1
1pqg8dpwthcp3 ? ? ? ? ? ?3 ? ? ? ? ?1
1pqg8dpwthcp3 ? ? ? ? ? ?4 ? ? ? ? ?1

SQL> ?select ?child_number,bind_mismatch from v$sql_shared_cursor where sql_id='1pqg8dpwthcp3';

CHILD_NUMBER B
------------ -
? ? ? ? ? ?1 N
? ? ? ? ? ?2 Y
? ? ? ? ? ?3 Y
? ? ? ? ? ?4 Y
具體可以參考:High Version Count Due To BIND_MISMATCH [ID 336268.1] ? ?

ORACLE文檔說可以通過設置10503事件來搞定這個問題 ,?10503 =>?enable user-specified graduated bind lengths


(1)查詢綁定變量最大長度:假如最大長度為128
select max(max_length) from v$sql_bind_metadata where datatype=1;


(2)在參數文件中設置:
event="10503 trace name context forever, level 128"

SQL> alter system set event='10503 trace name context forever, level 128' scope=spfile;


(3)該參數在會話級別雖然能夠成功設置,但是無效。
Bug 10274265 - Event 10503 does not work at session level [ID 10274265.8]
SQL> select * from v$version;BANNER

----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE ? ?10.2.0.1.0 ? ? ?Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production ??

SQL> alter system flush shared_pool;
系統已更改。


SQL> alter system set events '10503 ?trace name context forever ,level 4096';
系統已更改。

SQL> variable c varchar2(32);
SQL> exec :c := 'zheng';
SQL> select id from edu.zhhtest where name= :c and rownum=1;

SQL> variable c varchar2(33);
SQL> exec :c := 'zheng';
SQL> select id from edu.zhhtest where name= :c and rownum=1;


SQL> select sql_id,child_number,executions from v$sql where sql_text='select id from edu.zhhtest where name= :c and rownum=1';

SQL_ID??????? CHILD_NUMBER EXECUTIONS
------------- ------------ ----------
grzn6d2ak22j4??????????? 0????????? 2

SQL> select s.child_number, m.position, m.max_length,
???????? decode(m.datatype,1,'varchar2',2,'number',m.datatype) as datatype
? 3??? from v$sql s, v$sql_bind_metadata m
? 4??? where s.sql_id = 'grzn6d2ak22j4'
? 5??? and s.child_address = m.address
? 6??? order by 1, 2;

CHILD_NUMBER?? POSITION MAX_LENGTH DATATYPE
------------ ---------- ---------- ----------------------------------------
?????????? 0????????? 1?????? 4000 varchar2

?

?

Bind Graduation的目的是什么?可能原因有如下兩個:

?

  • bind peeking緩解,提供多次peeking機會
  • ?

    從效果來看,Oracle bind graduation會增加子游標的數量。如果單就bind peeking而言,在Oracle 11g的ACS(Adaptive Cursor Sharing)出現之前,

    Oracle綁定變量使用的子游標數量是很少的。Bind graduation出現之后,我們最直觀的感覺是child cursor增多,對應的執行計劃增多。

    原有的可能只用一個執行計劃可以覆蓋的綁定變量語句,可能要有多個執行計劃才能覆蓋。

    ?

    對綁定變量語句而言,每次生成子游標,就意味著要進行一次hard parse,就意味著要進行一次peeking。生成與Peeking value對應的執行計劃。

    代碼中對變量聲明長度的不一致,直接意味著不同的程序模塊和功能模塊。Oracle也許認為這樣出現bind peeking問題的幾率較高。于是取巧采用變量聲明的方式進行區分管理。

    同時,劃分區域又不是很多,從而限制了子游標出現的數量。多次peeking,形成多個子游標,配對更合適的執行計劃。

    ?

    ?2.?? 綁定變量存儲

    ?

    對執行計劃而言,Oracle是需要單獨分配內存空間給執行計劃進行保存的。如果其中有使用綁定變量,Oracle是會將綁定變量保存在child cursor中的。

    在分配varchar2類型的綁定變量大小空間時,使用bind graduation可以分配略小的適當空間。

    雖然會存在bind graduation現象,但是我們說實現graduation的分區數量是有限的。也就是說,即使多次生成child cursor,帶來version count過多的風險也是有限的。

    如果要是很極端的情況,比如項目組希望實現絕對的共享或者說變量數目較多引起version count過多,可以使用10503事件控制bind graduation的出現,或者直接在代碼中聲明

    varchar2(2000)的綁定變量即可。

    ?相關的視圖:

    • ?v$sql_bind_capture;
    • ?v$sql_bind_metadata?
    • ?v$sql_shared_cursor?
    • ?v$sql?
    • ?v$sqlarea

    select s.child_number, m.position, m.max_length,decode(m.datatype,1,'varchar2',2,'number',m.datatype) as datatype
    from v$sql s, v$sql_bind_metadata m where s.sql_id = 'abz9zj4ryuw67' and s.child_address = m.address order by 1, 2;

    select sql_id,child_number,bind_mismatch from v$sql_shared_cursor where sql_id='abz9zj4ryuw67';

    11GR2的測試結果是第一次會是BIND_LENGTH_UPGRADEABLE,然后才會出現BIND_MISMATCH,估計是單純的增加了綁定變量buffer的長度,從而生產一個新的計劃.

    而不是重新bind peeking 然后生產計劃。當對于一個SQL_ID有過一次bind_length_upgrade后,如果再次因為綁定變量長度不一樣,不能重用計劃是,就會bind peeking產生新的計劃。

    參考鏈接

    http://blog.itpub.net/17203031/viewspace-704144

    http://blog.itpub.net/17203031/viewspace-704348

    http://blog.itpub.net/758322/viewspace-750315/

    http://www.net527.cn/shujukuguanli/Oracle/2012/0407/22446.html

    轉載于:https://www.cnblogs.com/princessd8251/p/3843850.html

    總結

    以上是生活随笔為你收集整理的BIND_MISMATCH导致过多VERSION COUNT的问题的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。