oracle實驗記錄 (cursor_sharing(1)exact&force)

fufuh2o發表於2009-10-14

實驗看下cursor_sharing與histogram

SQL> show parameter cursor

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
cursor_sharing                       string      EXACT

 

FORCE

Forces statements that may differ in some literals, but are otherwise identical, to share a cursor, unless the literals affect the meaning of the statement.

SIMILAR

Causes statements that may differ in some literals, but are otherwise identical, to share a cursor, unless the literals affect either the meaning of the

statement or the degree to which the plan is optimized.

EXACT

Only allows statements with identical text to share the same cursor.

有以上3個值
exact必須精確
force:server 端強制繫結變數
similar:oracle存在histogram時對於不同的變數值重新解析,相當於SIMILAR=EXACT
不存時與force一樣

下面實驗

首先exact情況


SQL> show user
USER 為 "XH"
SQL> create table t3(a int);

 

SQL> ed
已寫入 file afiedt.buf

  1  declare
  2  begin
  3  for i in 1..100 loop
  4  insert into t3 values(i);
  5  end loop;
  6  commit;
  7* end;
SQL> /

PL/SQL 過程已成功完成。

SQL> execute dbms_stats.gather_table_stats('XH','T3');

PL/SQL 過程已成功完成。


SQL> show parameter cursor

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
cursor_sharing                       string      EXACT


SQL> select distinct sid from v$mystat;

       SID
----------
       136

SQL>

SQL> select b.name,a.value from v$sesstat a,v$statname b where a.statistic#=b.stati
stic# and a.sid=136  and b.name in('parse count (total)','parse count (hard)','open
ed cursors current','session cursor cache hits','session cursor cache count');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
opened cursors current                                                    0
session cursor cache hits                                                68
session cursor cache count                                               30
parse count (total)                                                     103
parse count (hard)                                                       20

 

SQL> select * from t3 where a=1;

         A
----------
         1

SQL> select b.name,a.value from v$sesstat a,v$statname b where a.statistic#=b.stati
stic# and a.sid=136  and b.name in('parse count (total)','parse count (hard)','open
ed cursors current','session cursor cache hits','session cursor cache count');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
opened cursors current                                                    0
session cursor cache hits                                                68
session cursor cache count                                               30
parse count (total)                                                     114
parse count (hard)                                                       21

SQL> select PREV_HASH_VALUE,sql_HASH_VALUE from v$session where sid=136;

PREV_HASH_VALUE SQL_HASH_VALUE
--------------- --------------
     1879812956              0

SQL> col sql_text format a30
SQL> select  SQL_TEXT,VERSION_COUNT,EXECUTIONS,PARSE_CALLS from v$sqlarea where has
h_value=1879812956;

SQL_TEXT                       VERSION_COUNT EXECUTIONS PARSE_CALLS
------------------------------ ------------- ---------- -----------
select * from t3 where a=1                 1          1           1

SQL> select sql_text,PARSE_CALLS,EXECUTIONS,CHILD_LATCH,CHILD_NUMBER from v$sql whe
re hash_value=1879812956;

SQL_TEXT                       PARSE_CALLS EXECUTIONS CHILD_LATCH CHILD_NUMBER
------------------------------ ----------- ---------- ----------- ------------
select * from t3 where a=1               1          1           3            0

SQL>

SQL> select * from t3 where a=2;

         A
----------
         2
SQL> select b.name,a.value from v$sesstat a,v$statname b where a.statistic#=b.stati
stic# and a.sid=136  and b.name in('parse count (total)','parse count (hard)','open
ed cursors current','session cursor cache hits','session cursor cache count');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
opened cursors current                                                    0
session cursor cache hits                                                68
session cursor cache count                                               30
parse count (total)                                                     115
parse count (hard)                                                       22


SQL> select PREV_HASH_VALUE,sql_HASH_VALUE from v$session where sid=136;

PREV_HASH_VALUE SQL_HASH_VALUE
--------------- --------------
      640433521              0


SQL> select sql_text,PARSE_CALLS,EXECUTIONS,CHILD_LATCH,CHILD_NUMBER from v$sql whe
re hash_value=640433521;

SQL_TEXT                       PARSE_CALLS EXECUTIONS CHILD_LATCH CHILD_NUMBER
------------------------------ ----------- ---------- ----------- ------------
select * from t3 where a=2               1          1           3            0

SQL> select sql_text,PARSE_CALLS,EXECUTIONS,CHILD_LATCH,CHILD_NUMBER from v$sql whe
re hash_value=640433521;

SQL_TEXT                       PARSE_CALLS EXECUTIONS CHILD_LATCH CHILD_NUMBER
------------------------------ ----------- ---------- ----------- ------------
select * from t3 where a=2               1          1           3            0


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


SQL> alter system flush shared_pool;

系統已更改。

SQL>
SQL> alter system set cursor_sharing=force;

 

SQL> select b.name,a.value from v$sesstat a,v$statname b where a.statistic#=b.stati
stic# and a.sid=136  and b.name in('parse count (total)','parse count (hard)','open
ed cursors current','session cursor cache hits','session cursor cache count');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
opened cursors current                                                    0
session cursor cache hits                                                 0
session cursor cache count                                                5
parse count (total)                                                      19
parse count (hard)                                                        5

 

SQL> select * from t3 where a=10;

         A
----------
        10


SQL> select PREV_HASH_VALUE,sql_HASH_VALUE from v$session where sid=136;

PREV_HASH_VALUE SQL_HASH_VALUE
--------------- --------------
      917182724              0

SQL> select sql_text,PARSE_CALLS,EXECUTIONS,CHILD_LATCH,CHILD_NUMBER from v$sql whe
re hash_value=917182724;

SQL_TEXT                       PARSE_CALLS EXECUTIONS CHILD_LATCH CHILD_NUMBER
------------------------------ ----------- ---------- ----------- ------------
select * from t3 where a=:"SYS           1          1           3            0
_B_0"

 

SQL> select * from t3 where a=11;

         A
----------
        11


SQL> select PREV_HASH_VALUE,sql_HASH_VALUE from v$session where sid=136;

PREV_HASH_VALUE SQL_HASH_VALUE
--------------- --------------
      917182724              0

SQL> select sql_text,PARSE_CALLS,EXECUTIONS,CHILD_LATCH,CHILD_NUMBER from v$sql whe
re hash_value=917182724;

SQL_TEXT                       PARSE_CALLS EXECUTIONS CHILD_LATCH CHILD_NUMBER
------------------------------ ----------- ---------- ----------- ------------
select * from t3 where a=:"SYS           2          2           3            0
_B_0"


SQL> select b.name,a.value from v$sesstat a,v$statname b where a.statistic#=b.stati
stic# and a.sid=136  and b.name in('parse count (total)','parse count (hard)','open
ed cursors current','session cursor cache hits','session cursor cache count');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
opened cursors current                                                    0
session cursor cache hits                                                 1
session cursor cache count                                               10
parse count (total)                                                      33
parse count (hard)                                                       10

SQL> select * from t3 where a=12;

         A
----------
        12

SQL> select b.name,a.value from v$sesstat a,v$statname b where a.statistic#=b.stati
stic# and a.sid=136  and b.name in('parse count (total)','parse count (hard)','open
ed cursors current','session cursor cache hits','session cursor cache count');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
opened cursors current                                                    0
session cursor cache hits                                                 1
session cursor cache count                                               16
parse count (total)                                                      34~~~
parse count (hard)                                                       10

SQL> select PREV_HASH_VALUE,sql_HASH_VALUE from v$session where sid=136;

PREV_HASH_VALUE SQL_HASH_VALUE
--------------- --------------
      917182724              0

SQL> select sql_text,PARSE_CALLS,EXECUTIONS,CHILD_LATCH,CHILD_NUMBER from v$sql whe
re hash_value=917182724;

SQL_TEXT                       PARSE_CALLS EXECUTIONS CHILD_LATCH CHILD_NUMBER
------------------------------ ----------- ---------- ----------- ------------
select * from t3 where a=:"SYS           3          3           3            0
_B_0"

SQL> select  SQL_TEXT,VERSION_COUNT,EXECUTIONS,PARSE_CALLS from v$sqlarea where has
h_value=917182724;

SQL_TEXT                       VERSION_COUNT EXECUTIONS PARSE_CALLS
------------------------------ ------------- ---------- -----------
select * from t3 where a=:"SYS             1          3           3
_B_0"

 

 

force  與peek
實驗表xh.t4  10000 rows , distinct 10000,
當使用a>1時應該  走FTS,A>9999時應該走INDEX RANGE SACN

SQL> select * from t4 where a>1;

執行計劃
----------------------------------------------------------
Plan hash value: 2560505625

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      | 10000 | 70000 |     6   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| T4   | 10000 | 70000 |     6   (0)| 00:00:01 |
--------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("A">1)

SQL> select * from t4 where a>9999;

執行計劃
----------------------------------------------------------
Plan hash value: 4096627024

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

| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time
     |

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

|   0 | SELECT STATEMENT            |        |     1 |     7 |     3   (0)| 00:0
0:01 |

|   1 |  TABLE ACCESS BY INDEX ROWID| T4     |     1 |     7 |     3   (0)| 00:0
0:01 |

|*  2 |   INDEX RANGE SCAN          | IND_T4 |     1 |       |     2   (0)| 00:0
0:01 |

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


Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("A">9999)

 

 

 

 

 

SQL> alter system set cursor_sharing=FORCE;

系統已更改。

SQL> alter system flush shared_pool;

系統已更改。
SQL> select b.name,a.value from v$sesstat a,v$statname b where a.statistic#=b.stati
stic# and a.sid=140  and b.name in('parse count (total)','parse count (hard)','open
ed cursors current','session cursor cache hits','session cursor cache count');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
opened cursors current                                                    8
session cursor cache hits                                              2048
session cursor cache count                                               30
parse count (total)                                                    1181
parse count (hard)                                                      208

 

SQL> select * from t4 where a>9999;

         A          B
---------- ----------
     10000      10001


SQL> select PREV_HASH_VALUE,sql_HASH_VALUE from v$session where sid=140;

PREV_HASH_VALUE SQL_HASH_VALUE
--------------- --------------
      314176702              0

SQL> select sql_text,PARSE_CALLS,EXECUTIONS,CHILD_LATCH,CHILD_NUMBER from v$sql whe
re hash_value=314176702;

SQL_TEXT                       PARSE_CALLS EXECUTIONS CHILD_LATCH CHILD_NUMBER
------------------------------ ----------- ---------- ----------- ------------
select * from t4 where a>:"SYS           1          1           3            0
_B_0"


SQL> select  SQL_TEXT,VERSION_COUNT,EXECUTIONS,PARSE_CALLS ,address from v$sqlarea
where hash_value=314176702;

SQL_TEXT                       VERSION_COUNT EXECUTIONS PARSE_CALLS ADDRESS
------------------------------ ------------- ---------- ----------- --------
select * from t4 where a>:"SYS             1          1           1 25568278
_B_0"


SQL> select b.name,a.value from v$sesstat a,v$statname b where a.statistic#=b.stati
stic# and a.sid=140  and b.name in('parse count (total)','parse count (hard)','open
ed cursors current','session cursor cache hits','session cursor cache count');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
opened cursors current                                                    8
session cursor cache hits                                              2106
session cursor cache count                                               29
parse count (total)                                                    1198
parse count (hard)                                                      225

SQL>

SQL> select * from t4 where a>9998;~~~還應該走INDEX

         A          B
---------- ----------
      9999      10000
     10000      10001

SQL>
SQL> select PREV_HASH_VALUE,sql_HASH_VALUE from v$session where sid=140;

PREV_HASH_VALUE SQL_HASH_VALUE
--------------- --------------
      314176702              0

SQL> select sql_text,PARSE_CALLS,EXECUTIONS,CHILD_LATCH,CHILD_NUMBER from v$sql whe
re hash_value=314176702;

SQL_TEXT                       PARSE_CALLS EXECUTIONS CHILD_LATCH CHILD_NUMBER
------------------------------ ----------- ---------- ----------- ------------
select * from t4 where a>:"SYS           2          2           3            0
_B_0"


SQL> select  SQL_TEXT,VERSION_COUNT,EXECUTIONS,PARSE_CALLS ,address from v$sqlarea
where hash_value=314176702;

SQL_TEXT                       VERSION_COUNT EXECUTIONS PARSE_CALLS ADDRESS
------------------------------ ------------- ---------- ----------- --------
select * from t4 where a>:"SYS             1          2           2 25568278
_B_0"


SQL> select b.name,a.value from v$sesstat a,v$statname b where a.statistic#=b.stati
stic# and a.sid=140  and b.name in('parse count (total)','parse count (hard)','open
ed cursors current','session cursor cache hits','session cursor cache count');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
opened cursors current                                                    8
session cursor cache hits                                              2106
session cursor cache count                                               29
parse count (total)                                                    1199~~~~~~~~~~~
parse count (hard)                                                      225

SQL> select * from t4 where a>1;

SQL> select PREV_HASH_VALUE,sql_HASH_VALUE from v$session where sid=140;

PREV_HASH_VALUE SQL_HASH_VALUE
--------------- --------------
      314176702              0

SQL> select sql_text,PARSE_CALLS,EXECUTIONS,CHILD_LATCH,CHILD_NUMBER from v$sql whe
re hash_value=314176702;

SQL_TEXT                       PARSE_CALLS EXECUTIONS CHILD_LATCH CHILD_NUMBER
------------------------------ ----------- ---------- ----------- ------------
select * from t4 where a>:"SYS           3          3           3            0
_B_0"


SQL> select  SQL_TEXT,VERSION_COUNT,EXECUTIONS,PARSE_CALLS ,address from v$sqlarea
where hash_value=314176702;

SQL_TEXT                       VERSION_COUNT EXECUTIONS PARSE_CALLS ADDRESS
------------------------------ ------------- ---------- ----------- --------
select * from t4 where a>:"SYS             1          3           3 25568278~~~沒產生子游標
_B_0"


SQL> select b.name,a.value from v$sesstat a,v$statname b where a.statistic#=b.stati
stic# and a.sid=140  and b.name in('parse count (total)','parse count (hard)','open
ed cursors current','session cursor cache hits','session cursor cache count');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
opened cursors current                                                    8
session cursor cache hits                                              2106
session cursor cache count                                               30~~~~~~~cursor CACHE HINT
parse count (total)                                                    1200~~~~~~~~還是一次 SOFT PARSE
parse count (hard)                                                      225

 

另一個SESSION 看下執行計劃
SQL> set autotrace trace exp
SQL> select * from xh.t4 where a>9999;

執行計劃
----------------------------------------------------------
Plan hash value: 4096627024

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

| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time
     |

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

|   0 | SELECT STATEMENT            |        |     1 |     7 |     3   (0)| 00:0
0:01 |

|   1 |  TABLE ACCESS BY INDEX ROWID| T4     |     1 |     7 |     3   (0)| 00:0
0:01 |

|*  2 |   INDEX RANGE SCAN          | IND_T4 |     1 |       |     2   (0)| 00:0
0:01 |

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


Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("A">9999)

SQL> select * from xh.t4 where a>1;

執行計劃
----------------------------------------------------------
Plan hash value: 2560505625

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      | 10000 | 70000 |     6   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| T4   | 10000 | 70000 |     6   (0)| 00:00:01 |
--------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("A">1)

可以看到 一個是  INDEX RANGE SACN,一個是FTS ,既然 A>1時候 計劃不一樣應該產生新的 子游標 並且HARD PARSE


SQL> select * from t4 where a>1;再執行一次

SQL> select PREV_HASH_VALUE,sql_HASH_VALUE from v$session where sid=140;

PREV_HASH_VALUE SQL_HASH_VALUE
--------------- --------------
      314176702              0

SQL> select sql_text,PARSE_CALLS,EXECUTIONS,CHILD_LATCH,CHILD_NUMBER from v$sql whe
re hash_value=314176702;

SQL_TEXT                       PARSE_CALLS EXECUTIONS CHILD_LATCH CHILD_NUMBER
------------------------------ ----------- ---------- ----------- ------------
select * from t4 where a>:"SYS           4          4           3            0
_B_0"


SQL> select  SQL_TEXT,VERSION_COUNT,EXECUTIONS,PARSE_CALLS ,address from v$sqlarea
where hash_value=314176702;

SQL_TEXT                       VERSION_COUNT EXECUTIONS PARSE_CALLS ADDRESS
------------------------------ ------------- ---------- ----------- --------
select * from t4 where a>:"SYS             1          4           4 25568278
_B_0"


SQL> select b.name,a.value from v$sesstat a,v$statname b where a.statistic#=b.stati
stic# and a.sid=140  and b.name in('parse count (total)','parse count (hard)','open
ed cursors current','session cursor cache hits','session cursor cache count');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
opened cursors current                                                    8
session cursor cache hits                                              2107~~~~~~~~~
session cursor cache count                                               30
parse count (total)                                                    1201
parse count (hard)                                                      225

還是沒有 產生新子游標,新hard parse,而是出現一次fast soft parse,完全共享直接使用~~

SQL> set autotrace off
SQL> select operation from v$sql_plan where hash_value='314176702';

OPERATION
------------------------------------------------------------
SELECT STATEMENT
TABLE ACCESS
INDEX
用v$sql_plan看~~~~A>1實際 是用了 INDEX RANGE SCAN 方式,這是由於oracle peeking,oracle 會窺視第一次輸入變數的實際值產生PLAN,然後一直用這個執行計劃,set

autotrace顯示的不對


再證實一下

SQL> alter system flush shared_pool;

系統已更改。

SQL> select b.name,a.value from v$sesstat a,v$statname b where a.statistic#=b.stati
stic# and a.sid=140  and b.name in('parse count (total)','parse count (hard)','open
ed cursors current','session cursor cache hits','session cursor cache count');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
opened cursors current                                                    8
session cursor cache hits                                              2163
session cursor cache count                                               30
parse count (total)                                                    1268
parse count (hard)                                                      231

SQL>
SQL> select  SQL_TEXT,VERSION_COUNT,EXECUTIONS,PARSE_CALLS ,address from v$sqlarea
where hash_value=314176702;

未選定行


SQL> select * from t4 where a>1;


SQL> select PREV_HASH_VALUE,sql_HASH_VALUE from v$session where sid=140;

PREV_HASH_VALUE SQL_HASH_VALUE
--------------- --------------
      314176702              0

SQL> select sql_text,PARSE_CALLS,EXECUTIONS,CHILD_LATCH,CHILD_NUMBER from v$sql whe
re hash_value=314176702;

SQL_TEXT                       PARSE_CALLS EXECUTIONS CHILD_LATCH CHILD_NUMBER
------------------------------ ----------- ---------- ----------- ------------
select * from t4 where a>:"SYS           1          1           3            0
_B_0"


SQL> select  SQL_TEXT,VERSION_COUNT,EXECUTIONS,PARSE_CALLS ,address from v$sqlarea
where hash_value=314176702;

SQL_TEXT                       VERSION_COUNT EXECUTIONS PARSE_CALLS ADDRESS
------------------------------ ------------- ---------- ----------- --------
select * from t4 where a>:"SYS             1          1           1 25568278
_B_0"


SQL> select b.name,a.value from v$sesstat a,v$statname b where a.statistic#=b.stati
stic# and a.sid=140  and b.name in('parse count (total)','parse count (hard)','open
ed cursors current','session cursor cache hits','session cursor cache count');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
opened cursors current                                                    8
session cursor cache hits                                              2181
session cursor cache count                                               29
parse count (total)                                                    1285
parse count (hard)                                                      232

SQL> select operation from v$sql_plan where hash_value='314176702';

OPERATION
------------------------------------------------------------
SELECT STATEMENT
TABLE ACCESS
SQL> select * from t4 where a>9999;

         A          B
---------- ----------
     10000      10001


SQL> select PREV_HASH_VALUE,sql_HASH_VALUE from v$session where sid=140;

PREV_HASH_VALUE SQL_HASH_VALUE
--------------- --------------
      314176702              0

SQL> select sql_text,PARSE_CALLS,EXECUTIONS,CHILD_LATCH,CHILD_NUMBER from v$sql whe
re hash_value=314176702;

SQL_TEXT                       PARSE_CALLS EXECUTIONS CHILD_LATCH CHILD_NUMBER
------------------------------ ----------- ---------- ----------- ------------
select * from t4 where a>:"SYS           2          2           3            0
_B_0"


SQL> select b.name,a.value from v$sesstat a,v$statname b where a.statistic#=b.stati
stic# and a.sid=140  and b.name in('parse count (total)','parse count (hard)','open
ed cursors current','session cursor cache hits','session cursor cache count');

NAME                                                                  VALUE
---------------------------------------------------------------- ----------
opened cursors current                                                    8
session cursor cache hits                                              2181
session cursor cache count                                               29
parse count (total)                                                    1286~~~~~~~~一次soft parse
parse count (hard)                                                      232

SQL> select  SQL_TEXT,VERSION_COUNT,EXECUTIONS,PARSE_CALLS ,address from v$sqlarea
where hash_value=314176702;

SQL_TEXT                       VERSION_COUNT EXECUTIONS PARSE_CALLS ADDRESS
------------------------------ ------------- ---------- ----------- --------
select * from t4 where a>:"SYS             1          2           2 25568278
_B_0"

SQL> select operation from v$sql_plan where hash_value='314176702';

OPERATION
------------------------------------------------------------
SELECT STATEMENT
TABLE ACCESS~~~~~~~~~~~~~~~~~~~~~~還是FTS,應該走INDEX RANGE SCAN,可以看出是由於oracle peek

 

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

相關文章