oracle 11g適應性子游標 改善PEEKING
10g 使用bind變數時候PEEKING 會造成執行計劃錯誤,11G進行了改進,但或多或少 會造成hard parse,兩方面的代價 要具體衡量,當然正確的執行計劃 是更重要的.
先看下 10G 情況
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Prod
PL/SQL Release 10.2.0.4.0 - Production
CORE 10.2.0.4.0 Production
TNS for Linux: Version 10.2.0.4.0 - Production
NLSRTL Version 10.2.0.4.0 - Production
peeking 受到這幾個隱藏引數影響
SQL> SQL> set linesize 132
column name format a30
column value format a25
select
x.ksppinm name,
y.ksppstvl value,
y.ksppstdf isdefault,
decode(bitand(y.ksppstvf,7),1,'MODIFIED',4,'SYSTEM_MOD','FALSE') ismod,
decode(bitand(y.ksppstvf,2),2,'TRUE','FALSE') isadj,x. KSPPDESC
from
sys.x$ksppi x,
sys.x$ksppcv y
where
x.inst_id = userenv('Instance') and
y.inst_id = userenv('Instance') and
x.indx = y.indx and
x.ksppinm like '%peek%'
order by
translate(x.ksppinm, ' _', ' ')
/
SQL> SQL> SQL> 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
NAME VALUE ISDEFAULT ISMOD ISADJ
------------------------------ ------------------------- --------- ---------- -----
KSPPDESC
------------------------------------------------------------------------------------------------------------------------------------
_optim_peek_user_binds TRUE TRUE FALSE FALSE
enable peeking of user binds
_px_bind_peek_sharing TRUE TRUE FALSE FALSE
enables sharing of px cursors that were built using bind peeking
_xpl_peeked_binds_log_size 8192 TRUE FALSE FALSE
maximum bytes for logging peeked bind values for V$SQL_PLAN (0 = OFF)
SQL> create table t1 (a int,b int);
Table created.
SQL> declare
2 begin
3 for i in 1..10000 loop
4 insert into t1 values(i,i+1);
5 end loop;
6 commit;
7 end;
8 /
PL/SQL procedure successfully completed.
SQL> execute dbms_stats.gather_table_stats('SYS','T1');
PL/SQL procedure successfully completed.
SQL> select count(*) from t1;
COUNT(*)
----------
10000
SQL> create index t1_ind on t1(a);
Index created.
SQL> set autotrace off
SQL> create index t1_ind on t1(a);
Index created.
SQL> set autotrace trace explain
SQL> select * from t1 where a>1;
Execution Plan
----------------------------------------------------------
Plan hash value: 3617692013
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9999 | 69993 | 6 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T1 | 9999 | 69993 | 6 (0)| 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("A">1)
SQL> select * from t1 where a>9000;
Execution Plan
----------------------------------------------------------
Plan hash value: 2059591622
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1000 | 7000 | 6 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| T1 | 1000 | 7000 | 6 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | T1_IND | 1000 | | 4 (0)| 00:00:01 |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("A">9000)
可以看到上面採用字面值的情況 ,下面使用BIND 變數
QL> variable a number
SQL> execute :a:=1
PL/SQL procedure successfully completed.
SQL> select * from t1 where a>:a;
Execution Plan
----------------------------------------------------------
Plan hash value: 2059591622
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 500 | 3500 | 3 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| T1 | 500 | 3500 | 3 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | T1_IND | 90 | | 2 (0)| 00:00:01 |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("A">TO_NUMBER(:A))
問題來了~~~按照PEEKING 的原則 至少oracle應該確認 BIND 值為1 走FTS ,但 顯示為INDEX RANGE SCAN
現在使用V$sql_plan來檢視執行計劃
SQL> alter system flush shared_pool;
System altered.
SQL> variable a number
SQL> execute :a:=1
PL/SQL procedure successfully completed.
select * from t1 where a>:a
SQL> col sql_text format a40
SQL> select hash_value ,sql_text from v$sqlarea where sql_text like '%select * from t1 where a>%';
HASH_VALUE SQL_TEXT
---------- ----------------------------------------
3711359813 select * from t1 where a>:a
2165387111 select hash_value ,sql_text from v$sqlar
ea where sql_text like '%select * from t
1 where a>
SQL> select operation,options,object_name,cardinality from v$sql_plan where hash_value='3711359813';
OPERATION OPTIONS
------------------------------ ------------------------------
OBJECT_NAME CARDINALITY
------------------------------ -----------
SELECT STATEMENT
TABLE ACCESS FULL
T1 9999
可以看到 set autotrace 不準確 ~~,具體應該依賴於v$sql_plan,下面繼續實驗
execute :a:=9000
select * from t1 where a>:a
;
SQL> select hash_value ,sql_text from v$sqlarea where sql_text like '%select * from t1 where a>%';
HASH_VALUE SQL_TEXT
---------- ----------------------------------------
3711359813 select * from t1 where a>:a
2165387111 select hash_value ,sql_text from v$sqlar
ea where sql_text like '%select * from t
1 where a>%'
SQL> select operation,
options,object_name,cardinality from v$sql_plan where hash_value='3711359813';
OPERATION OPTIONS
------------------------------ ------------------------------
OBJECT_NAME CARDINALITY
------------------------------ -----------
SELECT STATEMENT
TABLE ACCESS FULL
T1 9999
可以看到oracle peeking了一次,然後按第一次FTS 方式 共享CURSOR ,共享了FTS 的 EXECUTE PLAN
看下11G 情況
SQL> select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - Production
PL/SQL Release 11.1.0.6.0 - Production
CORE 11.1.0.6.0 Production
TNS for Linux: Version 11.1.0.6.0 - Productio
NLSRTL Version 11.1.0.6.0 - Production
SQL> create table t1 (a int, b int);
Table created.
SQL> declare
2 begin
3 for i in 1..10000 loop
4 insert into t1 values(i,i+1);
5 end loop;
6 commit;
7 end;
8 /
PL/SQL procedure successfully completed.
SQL> create index t1_ind on t1(a);
Index created.
SQL> execute dbms_stats.gather_table_stats('SYS','T1');
SQL> variable a number
SQL> execute :a:=1
PL/SQL procedure successfully completed.
select * from t1 where a>:a;
SQL> select hash_value ,sql_text from v$sqlarea where sql_text like '%select * from t1 where a>%';
HASH_VALUE SQL_TEXT
---------- ----------------------------------------
2165387111 select hash_value ,sql_text from v$sqlar
ea where sql_text like '%select * from t
1 where a>%'
2263578425 select * from t1 where a>:a
SQL> select operation,
2 options,object_name,cardinality from v$sql_plan where hash_value='2263578425';
OPERATION OPTIONS
------------------------------ ------------------------------
OBJECT_NAME CARDINALITY
------------------------------ -----------
SELECT STATEMENT
TABLE ACCESS FULL
T1 9999
SQL> execute :a:=9000
PL/SQL procedure successfully completed.
SQL> select * from t1 where a>:a;
SQL> select hash_value ,sql_text from v$sqlarea where sql_text like '%select * from t1 where a>%';
HASH_VALUE SQL_TEXT
---------- ----------------------------------------
2165387111 select hash_value ,sql_text from v$sqlar
ea where sql_text like '%select * from t
1 where a>%'
2263578425 select * from t1 where a>:a
SQL> select operation,
2 options,object_name,cardinality from v$sql_plan where hash_value='2263578425';
OPERATION OPTIONS
------------------------------ ------------------------------
OBJECT_NAME CARDINALITY
------------------------------ -----------
SELECT STATEMENT
TABLE ACCESS FULL
T1 9999
SQL> execute :a:=9999
PL/SQL procedure successfully completed.
SQL> select * from t1 where a>:a;
A B
---------- ----------
10000 10001
SQL> select hash_value ,sql_text from v$sqlarea where sql_text like '%select * from t1 where a>%';
HASH_VALUE SQL_TEXT
---------- ----------------------------------------
2165387111 select hash_value ,sql_text from v$sqlar
ea where sql_text like '%select * from t
1 where a>%'
2263578425 select * from t1 where a>:a
SQL> select operation,
2 options,object_name,cardinality from v$sql_plan where hash_value='2263578425';
OPERATION OPTIONS
------------------------------ ------------------------------
OBJECT_NAME CARDINALITY
------------------------------ -----------
SELECT STATEMENT
TABLE ACCESS BY INDEX ROWID
T1 1
INDEX RANGE SCAN
T1_IND 1
OPERATION OPTIONS
------------------------------ ------------------------------
OBJECT_NAME CARDINALITY
------------------------------ -----------
SELECT STATEMENT
TABLE ACCESS FULL
T1 9999
select * from t1 where a>9000; (9000的 時候也應該走INDEX )
SQL> select hash_value ,sql_text from v$sqlarea where sql_text like '%select * from t1 where a>9000%';
HASH_VALUE SQL_TEXT
---------- ----------------------------------------
705708754 select * from t1 where a>9000
1110618947 select hash_value ,sql_text from v$sqlar
ea where sql_text like '%select * from t
1 where a>9000%'
SQL> select operation,
2 options,object_name,cardinality from v$sql_plan where hash_value='705708754';
OPERATION OPTIONS
------------------------------ ------------------------------
OBJECT_NAME CARDINALITY
------------------------------ -----------
SELECT STATEMENT
TABLE ACCESS BY INDEX ROWID
T1 1000
INDEX RANGE SCAN
T1_IND 1000
SQL> select sql_id,child_number,plan_hash_value from v$sql where hash_value='2263578425'
2 /
SQL_ID CHILD_NUMBER PLAN_HASH_VALUE
------------- ------------ ---------------
5mu9n4f3fqxtt 0 3617692013
5mu9n4f3fqxtt 1 2059591622
產生了子游標,且產生了不同的執行計劃(plan_hash_value判斷 多了一個INDEX SCAN的plan)
SQL> select child_number,is_bind_sensitive,is_bind_aware,is_shareable from v$sql where sql_id='5mu9n4f3fqxtt' order by child_number;
CHILD_NUMBER I I I
------------ - - -
0 Y N Y
1 Y Y Y
SQL> select child_number,peeked,executions,rows_processed,buffer_gets from v$sql_cs_statistics where sql_id='5mu9n4f3fqxtt' order by child_number;
CHILD_NUMBER P EXECUTIONS ROWS_PROCESSED BUFFER_GETS
------------ - ---------- -------------- -----------
0 Y 1 9999 722
1 Y 1 1 3
SQL> select child_number,predicate,low,high from v$sql_cs_selectivity where sql_id='5mu9n4f3fqxtt' order by child_number;
CHILD_NUMBER PREDICATE LOW HIGH
------------ ---------------------------------------- ---------- ----------
1 >A 0.000090 0.000110
execute :a:=1000
select * from t1 where a>:a
這個計劃走的是FTS 又產生 一個version_count,
SQL> select child_number,peeked,executions,rows_processed,buffer_gets from v$sql_cs_statistics where sql_id='5mu9n4f3fqxtt' order by child_number;
CHILD_NUMBER P EXECUTIONS ROWS_PROCESSED BUFFER_GETS
------------ - ---------- -------------- -----------
0 Y 1 9999 722
1 Y 1 1 3
2 Y 1 9000 622
SQL> select child_number,is_bind_sensitive,is_bind_aware,is_shareable from v$sql where sql_id='5mu9n4f3fqxtt' order by child_number;
CHILD_NUMBER I I I
------------ - - -
0 Y N N
1 Y Y Y
2 Y Y Y
SQL> select child_number,predicate,low,high from v$sql_cs_selectivity where sql_id='5mu9n4f3fqxtt' order by child_number;
CHILD_NUMBER PREDICATE LOW HIGH
------------ ---------------------------------------- ---------- ----------
1 >A 0.000090 0.000110
2 >A 0.810081 0.990099
SQL> select sql_id,child_number,plan_hash_value from v$sql where hash_value='2263578425'
2 ;
SQL_ID CHILD_NUMBER PLAN_HASH_VALUE
------------- ------------ ---------------
5mu9n4f3fqxtt 0 3617692013
5mu9n4f3fqxtt 1 2059591622
5mu9n4f3fqxtt 2 3617692013
SQL> execute :a:=2000
PL/SQL procedure successfully completed.
select * from t1 where a>:a
SQL> select sql_id,child_number,plan_hash_value from v$sql where hash_value='2263578425';
SQL_ID CHILD_NUMBER PLAN_HASH_VALUE
------------- ------------ ---------------
5mu9n4f3fqxtt 0 3617692013
5mu9n4f3fqxtt 1 2059591622
5mu9n4f3fqxtt 2 3617692013
5mu9n4f3fqxtt 3 3617692013
SQL> select child_number,predicate,low,high from v$sql_cs_selectivity where sql_id='5mu9n4f3fqxtt' order by child_number;
CHILD_NUMBER PREDICATE LOW HIGH
------------ ---------------------------------------- ---------- ----------
1 >A 0.000090 0.000110
2 >A 0.810081 0.990099
3 >A 0.720072 0.990099
SQL> select child_number,peeked,executions,rows_processed,buffer_gets from v$sql_cs_statistics where sql_id='5mu9n4f3fqxtt' order by child_number;
CHILD_NUMBER P EXECUTIONS ROWS_PROCESSED BUFFER_GETS
------------ - ---------- -------------- -----------
0 Y 1 9999 722
1 Y 1 1 3
2 Y 1 9000 622
3 Y 1 8000 556
SQL> select child_number,is_bind_sensitive,is_bind_aware,is_shareable from v$sql where sql_id='5mu9n4f3fqxtt' order by child_number;
CHILD_NUMBER I I I
------------ - - -
0 Y N N
1 Y Y Y
2 Y Y N
3 Y Y Y
SQL> execute :a:=1500
PL/SQL procedure successfully completed.
select * from t1 where a>:a;
8500 rows selected.
SQL> select child_number,peeked,executions,rows_processed,buffer_gets from v$sql_cs_statistics where sql_id='5mu9n4f3fqxtt' order by child_number;
CHILD_NUMBER P EXECUTIONS ROWS_PROCESSED BUFFER_GETS
------------ - ---------- -------------- -----------
0 Y 1 9999 722
1 Y 1 1 3
2 Y 1 9000 622
3 Y 1 8000 556
SQL> select child_number,is_bind_sensitive,is_bind_aware,is_shareable from v$sql where sql_id='5mu9n4f3fqxtt' order by child_number;
CHILD_NUMBER I I I
------------ - - -
0 Y N N
1 Y Y Y
2 Y Y N
3 Y Y Y
SQL> select child_number,predicate,low,high from v$sql_cs_selectivity where sql_id='5mu9n4f3fqxtt' order by child_number;
CHILD_NUMBER PREDICATE LOW HIGH
------------ ---------------------------------------- ---------- ----------
1 >A 0.000090 0.000110
2 >A 0.810081 0.990099
3 >A 0.720072 0.990099
SQL> select sql_id,child_number,plan_hash_value from v$sql where hash_value='2263578425';
SQL_ID CHILD_NUMBER PLAN_HASH_VALUE
------------- ------------ ---------------
5mu9n4f3fqxtt 0 3617692013
5mu9n4f3fqxtt 1 2059591622
5mu9n4f3fqxtt 2 3617692013
5mu9n4f3fqxtt 3 3617692013
可以看到oracle 11g 在 :a:=9999時候 再次peeking ,9000的時候沒有PEEKING(否則就應該走了INDEX )
回到10G 看下
SQL> execute :a:=9999
PL/SQL procedure successfully completed.
SQL> select * from t1 where a>:a
2 ;
A B
---------- ----------
10000 10001
SQL> select hash_value ,sql_text from v$sqlarea where sql_text like '%select * from t1 where a>%';
HASH_VALUE SQL_TEXT
---------- ----------------------------------------
3711359813 select * from t1 where a>:a
2165387111 select hash_value ,sql_text from v$sqlar
ea where sql_text like '%select * from t
1 where a>%'
SQL> select operation,options,object_name,cardinality from v$sql_plan where hash_value='3711359813';
OPERATION OPTIONS
------------------------------ ------------------------------
OBJECT_NAME CARDINALITY
------------------------------ -----------
SELECT STATEMENT
TABLE ACCESS FULL
T1 9999
SQL> select sql_id,child_number,plan_hash_value from v$sql where hash_value='3711359813';
SQL_ID CHILD_NUMBER PLAN_HASH_VALUE
------------- ------------ ---------------
cgw5dngfmdqu5 0 3617692013
10g :a:=9999時候 還是走的FTS ,沒有子游標 都是用了一個PLAN (plan_hash_value判斷出來)
所以可以看出來 11G 出現了可適應cursor
但是有些問題 即便執行計劃一樣 同一個user執行相同SQL語句, 但還是產生了子游標 且最後對應的執行計劃都一樣~~~但還是硬解析
例
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Prod
PL/SQL Release 10.2.0.4.0 - Production
CORE 10.2.0.4.0 Production
TNS for Linux: Version 10.2.0.4.0 - Production
NLSRTL Version 10.2.0.4.0 - Production
SQL> select distinct sid from v$mystat;
SID
----------
159
SQL> show user
USER is "SYS"
SQL> alter system flush shared_pool;
System altered.
開另一個SESSION 查詢
SQL> show parameter optimizer_mode
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
optimizer_mode string ALL_ROWS
SQL> select b.name,a.value from v$sesstat a,v$statname b where a.statistic#=b.statistic# and a.sid=159 and b.name in('parse count (total)','parse count (hard)','open
2 ed cursors current','session cursor cache hits','session cursor cache count');
NAME VALUE
---------------------------------------------------------------- ----------
session cursor cache hits 2149
session cursor cache count 19
parse count (total) 1355
parse count (hard) 308
SQL> select * from t1 where a>9999;(sid 159)
A B
---------- ----------
10000 10001
SQL>
SQL> select b.name,a.value from v$sesstat a,v$statname b where a.statistic#=b.statistic# and a.sid=159 and b.name in('parse count (total)','parse count (hard)','open
2 ed cursors current','session cursor cache hits','session cursor cache count');
NAME VALUE
---------------------------------------------------------------- ----------
session cursor cache hits 2150
session cursor cache count 19
parse count (total) 1363
parse count (hard) 309~~~~~多了一次hard parse
QL> col sql_text format a30
SQL> select SQL_TEXT,VERSION_COUNT,EXECUTIONS,PARSE_CALLS from v$sqlarea where hash_value=1766722913;
SQL_TEXT VERSION_COUNT EXECUTIONS PARSE_CALLS
------------------------------ ------------- ---------- -----------
select * from t1 where a>9999 1 1 1
SQL> col sql_text format a30
SQL> select sql_id,child_number,plan_hash_value from v$sql where hash_value='1766722913';
SQL_ID CHILD_NUMBER PLAN_HASH_VALUE
------------- ------------ ---------------
107f0wtnnw3b1 0 2059591622
SQL> select b.name,a.value from v$sesstat a,v$statname b where a.statistic#=b.statistic# and a.sid=159 and b.name in('parse count (total)','parse count (hard)','open
2 ed cursors current','session cursor cache hits','session cursor cache count');
NAME VALUE
---------------------------------------------------------------- ----------
session cursor cache hits 2150
session cursor cache count 19
parse count (total) 1363
parse count (hard) 309~~~還是309~因為沒做任何操作
SQL> alter session set optimizer_mode=first_rows_10;
Session altered.
SQL> select * from t1 where a>9999;
A B
---------- ----------
10000 10001
SQL> select b.name,a.value from v$sesstat a,v$statname b where a.statistic#=b.statistic# and a.sid=159 and b.name in('parse count (total)','parse count (hard)','open
2 ed cursors current','session cursor cache hits','session cursor cache count');
NAME VALUE
---------------------------------------------------------------- ----------
session cursor cache hits 2150
session cursor cache count 20
parse count (total) 1365
parse count (hard) 310~~~~~新的hard parse
SQL>
SQL> select PREV_HASH_VALUE,sql_HASH_VALUE from v$session where sid=159;
PREV_HASH_VALUE SQL_HASH_VALUE
--------------- --------------
1766722913 0
SQL>
SQL> select sql_id,child_number,plan_hash_value from v$sql where hash_value='1766722913';
SQL_ID CHILD_NUMBER PLAN_HASH_VALUE
------------- ------------ ---------------
107f0wtnnw3b1 0 2059591622~~~~~~~~~~~~~顯然執行計劃 都是一樣的~但還是產生子游標,產生了hard parse
107f0wtnnw3b1 1 2059591622
SQL> col sql_text format a30
SQL> select SQL_TEXT,VERSION_COUNT,EXECUTIONS,PARSE_CALLS from v$sqlarea where hash_value=1766722913;
SQL_TEXT VERSION_COUNT EXECUTIONS PARSE_CALLS
------------------------------ ------------- ---------- -----------
select * from t1 where a>9999 2 3 3
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12020513/viewspace-622201/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle 11.1 自適應遊標Oracle
- [20180819]關於父子游標問題(11g).txt
- Oracle - 共享遊標、父子游標、硬軟解析Oracle
- 游標美化
- input 獲取游標位置與設定游標位置
- Vim游標移動
- Oracle之11g DataGuardOracle
- (12)mysql 中的游標MySql
- 阻止游標預設事件事件
- css 滑鼠游標設定CSS
- 【Swing】JTextField設定游標
- 【CURSOR】Oracle 子游標無法共享的原因之V$SQL_SHARED_CURSOROracleSQL
- win10游標怎麼縮放_win10游標縮放方法Win10
- cad游標大小怎麼調 cad游標中心正方形大小設定
- 【cbo計算公式】No Bind Peeking(五)公式
- Oracle 11G 安裝文件Oracle
- benchmark 壓測Oracle 11gOracle
- sysbench壓測Oracle 11gOracle
- 【CSS: cursor】滑鼠游標指標樣式大全CSS指標
- win10如何換滑鼠游標 win10更換滑鼠游標怎麼操作Win10
- win10 更改游標顏色方法 win10 滑鼠游標顏色怎麼改Win10
- Oracle 11G 安裝 bbed 工具Oracle
- oracle 11g data guard維護Oracle
- oracle 11g OEM在哪裡找到???Oracle
- oracle 11g 常用命令Oracle
- Oracle 11g RAC Silent Install For NFSOracleNFS
- Oracle 11g刪除庫重建Oracle
- Oracle 11G 修改scan_ipOracle
- Web 中的“選區”和“游標”Web
- AUTOCAD——調整十字游標
- Android 滑鼠游標的圖形合成Android
- Oracle 11G RAC叢集安裝(3)——安裝OracleOracle
- Oracle Linux 6.7 靜預設安裝Oracle 11gOracleLinux
- Oracle 11g RAC 監聽日常管理Oracle
- Oracle 11g 052題庫解析1Oracle
- oracle 11g datagurd主從切換Oracle
- ORACLE10G升級11GOracle
- Oracle 11g RAC手動新增serviceOracle
- Oracle 11g dg broker自動failoverOracleAI