【最佳化】引數SESSION_CACHED_CURSORS與解析之間的關係

不一樣的天空w發表於2016-10-15

一:引數SESSION_CACHED_CURSORS,就是說的是一個session可以快取多少個cursor(軟軟解析),讓後續相同的SQL語句不再開啟遊標,從而避免軟解析的過程來提高效能,軟解析同硬解析一樣,比較消耗資源

二:open_cursors設定每個session(會話)最多能同時開啟多少個cursor(遊標),是相對於SPA中的share poollibarary cache而言session_cached_cursor設定每個session(會話)最多可以快取多少個關閉掉的cursor,是相對於PGA而言

三:另外檢查SESSION_CACHED_CURSORS引數是否設定的合理,可以從兩個statistic來檢查,即select name,value from v$sysstat where name like '%cursor%';select name,value from v$sysstat where name like '%parse%';

 

1.創造環境:

SYS@ORA11GR2>create table t1 as select * from all_objects;

SYS@ORA11GR2>desc t1

SYS@ORA11GR2>select count(*) from t1;

 

  COUNT(*)

----------

     84999

 

2.當session_cached_cursors50進行操作

SYS@ORA11GR2>show parameter session_cached_cursors

 

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

session_cached_cursors               integer     50

 

1)直接進行查詢操作(無繫結變數):

SYS@ORA11GR2>select count(*) from t1 where object_id=101;

 

  COUNT(*)

----------

         1

 

SYS@ORA11GR2>select count(*) from t1 where object_id=102;

 

  COUNT(*)

----------

         1

 

SYS@ORA11GR2>select count(*) from t1 where object_id=103;

 

  COUNT(*)

----------

         1

 

驗證檢視解析執行情況:

SYS@ORA11GR2>select sql_text,s.parse_calls,loads,executions from v$sql s where sql_text like 'select count(*) from t1%' order by 1,2,3,4;

 

SQL_TEXT                                 PARSE_CALLS   LOADS   EXECUTIONS

---------------------------------------- ----------- ---------- ----------

select count(*) from t1 where object_id=101           1          1          1

select count(*) from t1 where object_id=102           1          1          1

select count(*) from t1 where object_id=103           1          1          1

三次執行SQL都是硬解析,都是解析1次,執行一次;

 

2)用繫結變數執行sql查詢語句:

SYS@ORA11GR2>var v_id number;

SYS@ORA11GR2>exec :v_id:=101;

 

PL/SQL procedure successfully completed.

 

SYS@ORA11GR2>select count(*) from t1 where object_id=:v_id;

 

  COUNT(*)

----------

         1

 

SYS@ORA11GR2>exec :v_id:=102;

 

PL/SQL procedure successfully completed.

 

SYS@ORA11GR2>select count(*) from t1 where object_id=:v_id;

 

  COUNT(*)

----------

         1

 

SYS@ORA11GR2>exec :v_id:=103;

 

PL/SQL procedure successfully completed.

 

SYS@ORA11GR2>select count(*) from t1 where object_id=:v_id;

 

  COUNT(*)

----------

         1

 

驗證檢視解析執行情況:

SYS@ORA11GR2>select sql_text,s.parse_calls,loads,executions from v$sql s where sql_text like 'select count(*) from t1%' order by 1,2,3,4;

 

SQL_TEXT                                 PARSE_CALLS      LOADS EXECUTIONS

---------------------------------------- ----------- ---------- ----------

select count(*) from t1 where object_id=101           1          1          1

select count(*) from t1 where object_id=102           1          1          1

select count(*) from t1 where object_id=103           1          1          1

select count(*) from t1 where object_id=:v_id         3          1          3


繫結變數執行的後執行三次,硬解析1此,軟解析2次,共解析3次,執行了3次,軟解析發揮了作用;

 
    

SYS@ORA11GR2>exec :v_id:=104;

 

PL/SQL procedure successfully completed.

 

SYS@ORA11GR2>select count(*) from t1 where object_id=:v_id;

 

  COUNT(*)

----------

         1
      

再次驗證檢視解析執行情況:

SYS@ORA11GR2>select sql_text,s.parse_calls,loads,executions from v$sql s where sql_text like 'select count(*) from t1%' order by 1,2,3,4;

 

SQL_TEXT                                 PARSE_CALLS      LOADS EXECUTIONS

---------------------------------------- ----------- ---------- ----------

select count(*) from t1 where object_id=101           1          1          1

select count(*) from t1 where object_id=102           1          1          1

select count(*) from t1 where object_id=103           1          1          1

select count(*) from t1 where object_id=:v_id         4          1          4

3)繫結變數迴圈執行五次操作:

begin
  for i in 1 .. 5 loop
    execute immediate 'select count(*) from t1 where object_id=:1'
      using i + 100;
  end loop;
end;
/

SYS@ORA11GR2>begin

  2   for i in 1..5 loop

  3     execute immediate 'select count(*) from t1 where object_id=:1' using i+100;

  4   end loop;

  5  end;

  6  /

 

PL/SQL procedure successfully completed.

 

驗證檢視解析執行情況:

SYS@ORA11GR2>select sql_text,s.parse_calls,loads,executions from v$sql s where sql_text like 'select count(*) from t1%' order by 1,2,3,4;

 

SQL_TEXT                                 PARSE_CALLS      LOADS EXECUTIONS

---------------------------------------- ----------- ---------- ----------

select count(*) from t1 where object_id=101           1          1       1 

select count(*) from t1 where object_id=102           1          1       1

select count(*) from t1 where object_id=103           1          1       1

select count(*) from t1 where object_id=:1            1          1        5 

SQL_TEXT                                 PARSE_CALLS      LOADS EXECUTIONS

---------------------------------------- ----------- ---------- ----------

select count(*) from t1 where object_id=:v_id         3          1       3


即總共解析了1次,而執行了五次,剩餘四次的執行也沒有經過解析就直接執行了,即軟軟解析

軟軟解析,定義為同一sql連續執行了三次以上,則將sql的執行計劃放到server processpga中,下次再執行同一sql時跳過解析階段直接執行。

 

 

3.session_cached_cursors=0時進行操作:

1)修改session_cached_cursor引數值為0

SYS@ORA11GR2>show parameter session_cached_cursor

 

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

session_cached_cursors               integer     50

SYS@ORA11GR2>alter system set session_cached_cursors=0 scope=spfile;

 

System altered.

 

SYS@ORA11GR2>shutdown immediate;

Database closed.

Database dismounted.

ORACLE instance shut down.

SYS@ORA11GR2>startup

ORACLE instance started.

 

Total System Global Area  830930944 bytes

Fixed Size                  2257800 bytes

Variable Size             503319672 bytes

Database Buffers          322961408 bytes

Redo Buffers                2392064 bytes

Database mounted.

Database opened.

SYS@ORA11GR2>show parameter session_cached_cursor

 

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

session_cached_cursors               integer     0

 

2)直接進行查詢操作(無繫結變數):

SYS@ORA11GR2>select count(*) from t1 where object_id=101;

 

  COUNT(*)

----------

         1

 

SYS@ORA11GR2>select count(*) from t1 where object_id=102;

 

  COUNT(*)

----------

         1

 

SYS@ORA11GR2>select count(*) from t1 where object_id=103;

 

  COUNT(*)

----------

         1

 

驗證檢視解析執行情況:

SYS@ORA11GR2>select sql_text,s.parse_calls,loads,executions from v$sql s where sql_text like 'select count(*) from t1%' order by 1,2,3,4;

 

SQL_TEXT                                 PARSE_CALLS      LOADS EXECUTIONS

---------------------------------------- ----------- ---------- ----------
select count(*) from t1 where object_id=101           1          1          1
select count(*) from t1 where object_id=102           1          1          1
select count(*) from t1 where object_id= 103          1          1          1

三次硬解析

 

3)用繫結變數執行sql查詢語句:

SYS@ORA11GR2>var v_id number;

SYS@ORA11GR2>exec :v_id:=101;

 

PL/SQL procedure successfully completed.

 

SYS@ORA11GR2>select count(*) from t1 where object_id=:v_id;

 

  COUNT(*)

----------

         1

 

SYS@ORA11GR2>exec :v_id:=102;

 

PL/SQL procedure successfully completed.

 

SYS@ORA11GR2>select count(*) from t1 where object_id=:v_id;

 

  COUNT(*)

----------

         1

 

SYS@ORA11GR2>exec :v_id:=103;

 

PL/SQL procedure successfully completed.

 

SYS@ORA11GR2>select count(*) from t1 where object_id=:v_id;

 

  COUNT(*)

----------

         1

驗證檢視解析執行情況:

SYS@ORA11GR2>select sql_text,s.parse_calls,loads,executions from v$sql s where sql_text like 'select count(*) from t1%' order by 1,2,3,4;

 

SQL_TEXT                                 PARSE_CALLS      LOADS EXECUTIONS

---------------------------------------- ----------- ---------- ----------

select count(*) from t1 where object_id=101           1          1          1

select count(*) from t1 where object_id=102           1          1          1

select count(*) from t1 where object_id=103           1          1          1

select count(*) from t1 where object_id=:v_id       3          1          3


軟解析,共
3次解析,後2次軟解析,執行3次;

 

4)繫結變數迴圈執行五次操作:
begin
  for i in 1 .. 5 loop
    execute immediate 'select count(*) from t1 where object_id=:1'
      using i + 100;
  end loop;
end;
/

SYS@ORA11GR2>begin

  2   for i in 1..5 loop

  3     execute immediate 'select count(*) from t1 where object_id=:1' using i+100;

  4   end loop;

  5  end;

  6  /

 

PL/SQL procedure successfully completed.

 

驗證檢視解析執行情況:

SYS@ORA11GR2>select sql_text,s.parse_calls,loads,executions from v$sql s where sql_text like 'select count(*) from t1%' order by 1,2,3,4;

 

SQL_TEXT                                 PARSE_CALLS      LOADS EXECUTIONS

---------------------------------------- ----------- ---------- ----------

select count(*) from t1 where object_id=101           1          1          1

select count(*) from t1 where object_id=102           1          1          1

select count(*) from t1 where object_id=103           1          1          1

select count(*) from t1 where object_id=:1           5          1          5

select count(*) from t1 where object_id=:v_id        3          1          3


此次沒有引數軟軟解析,表明當session_cached_cursors值設為0時,不產生軟軟解析(不管同一語句執行了多少次);

 

open_cursorssession_cached_cursor

a、兩個引數之間沒有任何關係,相互也不會有任何影響。

b、兩個引數有著相同的作用:讓後續相同的sql語句不在開啟遊標,從而避免軟解析過程來提供應用程式的效率。

Cpga中的cursor(軟軟解析)管理採用LRU原則當一個session打算parse一個sql,它會先去pga內搜尋session cursor cache list,如果找到那麼會把這個cursor脫離list,然後當關閉的時候再把這個cursor加到MRU.session_cached_cursor提供了快速軟分析的功能,提供了比soft parse更高的效能.


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31397003/viewspace-2126425/,如需轉載,請註明出處,否則將追究法律責任。

相關文章