初始化參數之cursor_sharing


一、Cursor_sharing簡介:

    這個參數是用來告訴Oracle在什么情況下可以共享游標,即SQL重用。

    Cursor_sharing參數有3個值可以設置:

     1)、EXACT:通常來說,exact值是Oracle推薦的,也是默認的,它要求SQL語句在完全相同時才會重用,否則會被重新執行硬解析操作

     2)、SIMILAR:similar是在Oracle認為某條SQL語句的謂詞條件可能會影響到它的執行計划時,才會被重新分析,否則將重用SQL

     3)、FORCE:force是在任何情況下,無條件重用SQL

   備注:上面所說的SQL重用,僅僅是指謂詞條件不同的SQL語句,實際上這樣的SQL基本上都在執行同樣的業務操作。

二、在Cursor_sharing參數值不同的時對SQL的影響:

   2.1 創建實驗環境:

 ----首先創建一張jack表----
1
SQL> create table jack (id int,name varchar2(10)); 2 3 Table created. 4 ----產生一些數據----
5
SQL> insert into jack values(1,'aa'); 6 7 1 row created. 8 9 SQL> insert into jack values(2,'bb'); 10 11 1 row created. 12 13 SQL> insert into jack values(3,'cc'); 14 15 1 row created. 16 17 SQL> insert into jack values(4,'dd'); 18 19 1 row created. 20 21 SQL> commit; 22 23 Commit complete. 24 25 SQL> select * from jack; 26 27 ID NAME 28 ---------- ---------- 29 1 aa 30 2 bb 31 3 cc 32 4 dd 33 ----創建下面實驗將要用到的三張表----
34
SQL> create table jack_exact as select * from jack; 35 36 Table created. 37 38 SQL> create table jack_similar as select * from jack; 39 40 Table created. 41 42 SQL> create table jack_force as select * from jack; 43 44 Table created. 45 ----查看該session的trace文件的路徑----
46
SQL> @/u01/scripts/showtrace 47 48 trace_file_name 49 -------------------------------------------------------------------------------- 50 /u01/app/oracle/diag/rdbms/yft/yft/trace/yft_ora_5329.trc

  2.2 cursor_sharing=exact的情況:

  ----將cursor_sharing設置為exact----
1
SQL> alter session set cursor_sharing=exact; 2 3 Session altered. 4 5 SQL> alter session set sql_trace=true; 6 7 Session altered. 8 9 SQL> select * from jack_exact where id=1; 10 11 ID NAME 12 ---------- ---------- 13 1 aa 14 15 SQL> select * from jack_exact where id=3; 16 17 ID NAME 18 ---------- ---------- 19 3 cc 20
21
SQL> select * from jack_exact where id=1; 22 23 ID NAME 24 ---------- ---------- 25 1 aa 26 27 SQL> alter session set sql_trace=false; 28 29 Session altered. 30 ----從下面的查詢可以看出執行了兩次硬解析----
31
SQL> select sql_text from v$sql where sql_text like 'select * from jack_exact where%'; 32 33 SQL_TEXT 34 -------------------------------------------------------------------------------- 35 select * from jack_exact where id=1 36 select * from jack_exact where id=3 37 ----查看trace文件,通過tkprof工具
[oracle@yft ~]$ tkprof /u01/app/oracle/diag/rdbms/yft/yft/trace/yft_ora_5329.trc out.txt aggregate=no sys=no----
38
SQL ID: fnggytkynxz04 39 Plan Hash: 4127630146 40 select * 41 from 42 jack_exact where id=1 43 44 45 call count cpu elapsed disk query current rows 46 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- 47 Parse 1 0.00 0.00 0 1 0 0 48 Execute 1 0.00 0.00 0 0 0 0 49 Fetch 2 0.00 0.00 0 4 0 1 50 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- 51 total 4 0.00 0.00 0 5 0 1 52 53 Misses in library cache during parse: 1 ---id=1,執行一次硬解析 54 Optimizer mode: ALL_ROWS 55 Parsing user id: 105 56 57 Rows Row Source Operation 58 ------- --------------------------------------------------- 59 1 TABLE ACCESS FULL JACK_EXACT (cr=4 pr=0 pw=0 time=0 us cost=3 size=20 card=1) 60 61 ******************************************************************************** 62 63 SQL ID: 1n0paamkf7sup 64 Plan Hash: 4127630146 65 select * 66 from 67 jack_exact where id=3 68 69 70 call count cpu elapsed disk query current rows 71 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- 72 Parse 1 0.00 0.00 0 1 0 0 73 Execute 1 0.00 0.00 0 0 0 0 74 Fetch 2 0.00 0.00 0 4 0 1 75 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- 76 total 4 0.00 0.00 0 5 0 1 77 78 Misses in library cache during parse: 1 ----id=3,執行一次硬解析 79 Optimizer mode: ALL_ROWS 80 Parsing user id: 105 81 82 Rows Row Source Operation 83 ------- --------------------------------------------------- 84 1 TABLE ACCESS FULL JACK_EXACT (cr=4 pr=0 pw=0 time=0 us cost=3 size=20 card=1) 85 86 ******************************************************************************** 87 88 SQL ID: fnggytkynxz04 89 Plan Hash: 4127630146 90 select * 91 from 92 jack_exact where id=1 93 94 95 call count cpu elapsed disk query current rows 96 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- 97 Parse 1 0.00 0.00 0 0 0 0 98 Execute 1 0.00 0.00 0 0 0 0 99 Fetch 2 0.00 0.00 0 4 0 1 100 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- 101 total 4 0.00 0.00 0 4 0 1 102 103 Misses in library cache during parse: 0 ----執行一次軟解析 104 Optimizer mode: ALL_ROWS 105 Parsing user id: 105 106 107 Rows Row Source Operation 108 ------- --------------------------------------------------- 109 1 TABLE ACCESS FULL JACK_EXACT (cr=4 pr=0 pw=0 time=0 us cost=3 size=20 card=1) 110 111 ********************************************************************************
  總結:當cursor_sharing=exact時,只有當SQL語句是完全一樣的情況下才能被重用。

   2.3 cursor_sharing=similar的情況:

 ----將curor_sharing設置為similar----
1
SQL> alter session set cursor_sharing=similar; 2 3 Session altered. 4 5 SQL> alter session set sql_trace=true; 6 7 Session altered. 8 9 SQL> select * from jack_similar where id=1; 10 11 ID NAME 12 ---------- ---------- 13 1 aa 14 15 SQL> select * from jack_similar where id=4; 16 17 ID NAME 18 ---------- ---------- 19 4 dd 20 21 SQL> select * from jack_similar where id=8; 22 23 no rows selected 24 ----下面查詢中可以看到Oracle將SQL中的謂詞條件用同一個名詞的一個變量替代,盡管看起來是一樣的,但是Oracle依然把它們作為兩條SQL來處理----
25
SQL> select sql_text from v$sql where sql_text like 'select * from jack_similar where%'; 26 27 SQL_TEXT 28 -------------------------------------------------------------------------------- 29 select * from jack_similar where id=:"SYS_B_0" 30 select * from jack_similar where id=:"SYS_B_0" 31 select * from jack_similar where id=:"SYS_B_0" 32 33 SQL> alter session set sql_trace=false; 34 35 Session altered. 36 37 [oracle@yft ~]$ tkprof /u01/app/oracle/diag/rdbms/yft/yft/trace/yft_ora_5329.trc out.txt sys=no 38 39 TKPROF: Release 11.2.0.1.0 - Development on Tue Jan 22 10:18:16 2013 40 41 Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved. 42 ----從trace文件中可以清楚看到上面的結論----
43
SQL ID: 80chtmbbwpx49 44 Plan Hash: 1559066762 45 select * 46 from 47 jack_similar where id=:"SYS_B_0" 48 49 50 call count cpu elapsed disk query current rows 51 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- 52 Parse 3 0.00 0.00 0 0 0 0 53 Execute 3 0.00 0.00 0 3 0 0 54 Fetch 5 0.00 0.00 0 10 0 2 55 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- 56 total 11 0.01 0.01 0 13 0 2 57 58 Misses in library cache during parse: 3 ----進行三次查詢,都各執行了一次硬解析。 59 Optimizer mode: ALL_ROWS 60 Parsing user id: 105 61 62 Rows Row Source Operation 63 ------- --------------------------------------------------- 64 1 TABLE ACCESS FULL JACK_SIMILAR (cr=4 pr=0 pw=0 time=0 us cost=3 size=20 card=1) 65 66 ********************************************************************************

     對於SIMILAR的情況,如果CBO發現被綁定變量的謂詞還有其他的執行計划可以選擇時,如果謂詞條件的值有變化,就將會產生一個新的子游標,而不是重用之前的SQL;如果謂詞沒有其他的執行計划可選擇,則忽略謂詞的值,重用之前的SQL。
     上面的例子還不能足以說明該情況,接着下面的模擬:

  ----清楚一下shared_pool中的內容,否則會影響后面的輸出----
1
SQL> alter system flush shared_pool; 2 3 System altered. 4 5 SQL> select * from jack_similar; 6 7 ID NAME 8 ---------- ---------- 9 1 aa 10 2 bb 11 3 cc 12 4 dd 13 14 SQL> insert into jack_similar values(1,'gg'); 15 16 1 row created. 17 18 SQL> commit; 19 20 Commit complete. 21 ----創建索引,並進行分析----
22
SQL> create index jack_similar_ind on jack_similar(id); 23 24 Index created. 25 SQL> exec dbms_stats.gather_table_stats(user,'jack_similar',cascade=>true); 26 27 PL/SQL procedure successfully completed. 28 29 SQL> select * from jack_similar; 30 31 ID NAME 32 ---------- ---------- 33 1 aa 34 2 bb 35 3 cc 36 4 dd 37 1 gg 38 39 SQL> alter session set cursor_sharing=similar; 40 41 Session altered. 42 43 SQL> alter session set sql_trace=true; 44 45 Session altered. 46 47 SQL> select * from jack_similar where id=1 and name='aa'; 48 49 ID NAME 50 ---------- ---------- 51 1 aa 52 53 SQL> select * from jack_similar where id=1 and name='gg'; 54 55 ID NAME 56 ---------- ---------- 57 1 gg 58 59 SQL> alter session set sql_trace=false; 60 61 Session altered. 62 ----在這里可以看到執行兩次SQL查詢,只進行了一個硬解析----
63
SQL> select sql_text from v$sql where sql_text like 'select * from jack_similar where%'; 64 65 SQL_TEXT 66 -------------------------------------------------------------------------------- 67 select * from jack_similar where id=:"SYS_B_0" and name=:"SYS_B_1" 68 69 ----在trace文件也驗證了這一點。----
----雖然name的值發生了改變,但是id的值沒有發生變,而id上有索引的,name上沒有索引,CBO認為這樣的情況不會改變SQL的執行計划。
70
SQL ID: 10ku2kuy1sqaj 71 Plan Hash: 2730352089 72 select * 73 from 74 jack_similar where id=:"SYS_B_0" and name=:"SYS_B_1" 75 76 77 call count cpu elapsed disk query current rows 78 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- 79 Parse 1 0.00 0.00 0 0 0 0 80 Execute 1 0.00 0.00 0 0 0 0 81 Fetch 2 0.00 0.00 0 4 0 1 82 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- 83 total 4 0.00 0.00 0 4 0 1 84 85 Misses in library cache during parse: 1 86 Optimizer mode: ALL_ROWS 87 Parsing user id: 105 88 89 Rows Row Source Operation 90 ------- --------------------------------------------------- 91 1 TABLE ACCESS BY INDEX ROWID JACK_SIMILAR (cr=4 pr=0 pw=0 time=0 us cost=3 size=6 card=1) 92 2 INDEX RANGE SCAN JACK_SIMILAR_IND (cr=2 pr=0 pw=0 time=17 us cost=1 size=0 card=2)(object id 75044) 93 94 ******************************************************************************** 95 96 SQL ID: 10ku2kuy1sqaj 97 Plan Hash: 2730352089 98 select * 99 from 100 jack_similar where id=:"SYS_B_0" and name=:"SYS_B_1" 101 102 103 call count cpu elapsed disk query current rows 104 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- 105 Parse 1 0.00 0.00 0 0 0 0 106 Execute 1 0.00 0.00 0 0 0 0 107 Fetch 2 0.00 0.00 0 4 0 1 108 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- 109 total 4 0.00 0.00 0 4 0 1 110 111 Misses in library cache during parse: 0 112 Optimizer mode: ALL_ROWS 113 Parsing user id: 105 114 115 Rows Row Source Operation 116 ------- --------------------------------------------------- 117 1 TABLE ACCESS BY INDEX ROWID JACK_SIMILAR (cr=4 pr=0 pw=0 time=0 us cost=3 size=6 card=1) 118 2 INDEX RANGE SCAN JACK_SIMILAR_IND (cr=2 pr=0 pw=0 time=3 us cost=1 size=0 card=2)(object id 75044) 119 120 ********************************************************************************

  2.4 cursor_sharing=force的情況

  ----設置cursor_sharing=force----
1
SQL> alter session set cursor_sharing=force; 2 3 Session altered. 4 5 SQL> alter session set sql_trace=true; 6 7 Session altered. 8 9 SQL> select * from jack_force where id=1; 10 11 ID NAME 12 ---------- ---------- 13 1 aa 14 15 SQL> select * from jack_force where id=4; 16 17 ID NAME 18 ---------- ---------- 19 4 dd 20 21 SQL> select * from jack_force where id=1; 22 23 ID NAME 24 ---------- ---------- 25 1 aa 26 27 SQL> alter session set sql_trace=false; 28 29 Session altered. 30 ----從下面的查詢中可以看出只進行了一次硬解析,而且使用了綁定變量----
31
SQL> select sql_text from v$sql where sql_text like 'select * from jack_force where%'; 32 33 SQL_TEXT 34 -------------------------------------------------------------------------------- 35 select * from jack_force where id=:"SYS_B_0" 36 37 ----查看trace文件內容----
38
[oracle@yft ~]$ tkprof /u01/app/oracle/diag/rdbms/yft/yft/trace/yft_ora_5551.trc aggregate=no sys=no 39 40 SQL ID: 38vy9d4quwdwk 41 Plan Hash: 1272021682 42 select * 43 from 44 jack_force where id=:"SYS_B_0" 45 46 47 call count cpu elapsed disk query current rows 48 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- 49 Parse 1 0.01 0.01 0 1 0 0 50 Execute 1 0.00 0.00 0 1 0 0 51 Fetch 2 0.00 0.00 0 4 0 1 52 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- 53 total 4 0.01 0.01 0 6 0 1 54 55 Misses in library cache during parse: 1 ----id=1的時候進行一次硬解析 56 Optimizer mode: ALL_ROWS 57 Parsing user id: 105 58 59 Rows Row Source Operation 60 ------- --------------------------------------------------- 61 1 TABLE ACCESS FULL JACK_FORCE (cr=4 pr=0 pw=0 time=0 us cost=3 size=20 card=1) 62 63 ******************************************************************************** 64 65 SQL ID: 38vy9d4quwdwk 66 Plan Hash: 1272021682 67 select * 68 from 69 jack_force where id=:"SYS_B_0" 70 71 72 call count cpu elapsed disk query current rows 73 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- 74 Parse 1 0.00 0.00 0 0 0 0 75 Execute 1 0.00 0.00 0 0 0 0 76 Fetch 2 0.00 0.00 0 3 0 1 77 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- 78 total 4 0.00 0.00 0 3 0 1 79 80 Misses in library cache during parse: 0 ----id=4的時候進行0次硬解析,一次軟解析 81 Optimizer mode: ALL_ROWS 82 Parsing user id: 105 83 84 Rows Row Source Operation 85 ------- --------------------------------------------------- 86 1 TABLE ACCESS FULL JACK_FORCE (cr=3 pr=0 pw=0 time=0 us cost=3 size=20 card=1) 87 88 ******************************************************************************** 89 90 SQL ID: 38vy9d4quwdwk 91 Plan Hash: 1272021682 92 select * 93 from 94 jack_force where id=:"SYS_B_0" 95 96 97 call count cpu elapsed disk query current rows 98 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- 99 Parse 1 0.00 0.00 0 0 0 0 100 Execute 1 0.00 0.00 0 0 0 0 101 Fetch 2 0.00 0.00 0 4 0 1 102 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- 103 total 4 0.00 0.00 0 4 0 1 104 105 Misses in library cache during parse: 0 ----id=1時進行0次硬解析,一次軟解析 106 Optimizer mode: ALL_ROWS 107 Parsing user id: 105 108 109 Rows Row Source Operation 110 ------- --------------------------------------------------- 111 1 TABLE ACCESS FULL JACK_FORCE (cr=4 pr=0 pw=0 time=0 us cost=3 size=20 card=1) 112 113 ********************************************************************************
總結:force是在任何情況下,無條件重用SQL。

 三、總結:

   FORCE和SIMIALR最大的區別在於,FORCE會把所有的謂詞用變量代替,並且不管變量的值如何,一律重用第一條SQL語句,而SIMILAR會根據謂詞的不同,來重新選擇SQL的執行計划。

   如果一個系統,它存在變量綁定的問題,並且這種問題已經影響到了系統的性能,這時候可以考慮將參數cursor_sharing的值設置為SIMILAR或FORCE來改善這種局面,不過在改成SIMILAR或FORCE都可能帶來一些Bug以及很多未知的東西,所以需要慎用。

   最后需要說明一點,對於OLTP系統,如果綁定變量情況不好的話,也許可以考慮通過設置這個參數來緩解一下問題;對於是在OLAP系統上,這個參數應該設置成EXACT,並且不應該使用綁定變量,因為在OLAP系統中,SQL的解析對於SQL的執行來看,話費的代價幾乎可以忽略,而正確的SQL執行計划才是OLAP數據庫最需要關注的。

四、引用Reference

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM