sql_shared_cursor (轉)
ORACLE使用子游標去區分一個不能被共享的SQL,因為雖然SQL相同,但是SQL所指向的物件使不同的。也就是說,這些SQL的父遊標都是一樣的,HASH_VALUE值都相同。例如,資料庫有三個表T,有這樣一個語句,select *from T,由於每個T都被不同的物件使用或是使用者使用,而在資料庫級別,這些語句都是一樣的,HASH_VALUE都相同,但是他們的子游標就不同了,這就會產生High Version Counts,由於HASH_VALUE相同,持有LATCH會不放,所以當PARSE的時候就會產生LATCH FREE。這是產生High Version的一個方面。另外正如大家前面所說的,資料庫的BUG也會引發這個問題。至於第一個問題,可以透過查詢V$SQL_SHARED_CURSOR 得到詳細關於子游標不能共享的原因,具體不再描述[@more@]
In addition to bind size change, data type change also causes Bind Mismatch,
not Type Check Mismatch, at least according to v$sql_shared_cursor. (for more
info about this view, see Note:296377.1)
SQL> create table t (s varchar2(10));
Table created.
SQL> declare
2 s_var varchar2(10) := 'a string';
3 n_var number := 123;
4 begin
5 insert into t (s) values (s_var);
6 insert into t (s) values (n_var);
7 end;
8 /
PL/SQL procedure successfully completed.
SQL> col sql_text for a50
SQL> select address, child_address, sql_text from v$sql where lower(sql_text) like 'insert into t (s) %';
ADDRESS CHILD_AD SQL_TEXT
-------- -------- --------------------------------------------------
7A3B1920 7A38F464 INSERT into t (s) values (:b1)
7A3B1920 7A38ECB8 INSERT into t (s) values (:b1)
-- The above two SQLs have the same sql_text but are not shared. Hence two
-- entries in v$sql with the same address and hash_value, but different
-- child_address, due to bind value data type difference (note the column
-- Bind_Mismatch). Replace kglhdpar with address in 10g.
SQL> select * from v$sql_shared_cursor where kglhdpar = '7A3B1920';
ADDRESS KGLHDPAR U S O O S L S E B P I S T A B D L T R I I R L I O S M U T N F
-------- -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
7A38F464 7A3B1920 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N
7A38ECB8 7A3B1920 N N N N N N N N N N N N N N Y N N N N N N N N N N N N N N N N
^
That B is Bind_Mismatch.
--------------------------------------------------------------------------------
> Questions about translating v$sql_shared_cursor.
>
> First, for my particular SQL, I found there are 1026 child cursors.
> But when I plug in the address to v$sql_shared_cursor, it only
> returned 5. So my question is why not 1026?
>
> Here is SQL's with excessive child cursors:
>
> HASH_VALUE ADDRESS COUNT(*)
> ---------- ---------------- ----------
> 10714010 0000000906F1FA70 1026
> 10714010 000000092AEF20E0 438
> 2786767810 00000008D7FEC5C8 1026 2786767810 000000091FBECF20 791
> 3584469599 0000000906F25A48 1026
> 3584469599 000000092AC78870 796
>
> I am interested in the one pointed to above.
>
> SQL> select * from v$sql_shared_cursor where KGLHDPAR = hextoraw('00000008D7FEC5C8');
>
> ADDRESS KGLHDPAR U S O O S L S E B P I S T A B D L T R I I R L I O S M U T N F
> ---------------- ---------------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
> 0000000911FE1910 00000008D7FEC5C8 N N N N N N N N N N N N N N Y N N N N N N N N N N N N N N N N
> 000000090B258D10 00000008D7FEC5C8 N N N N N N N N N N N N N N Y N N N N N N N N N N N N N N N N
> 0000000903A45028 00000008D7FEC5C8 N N N N N N N N N N N N N N Y N N N N N N N N N N N N N N N N
> 00000009193B26B0 00000008D7FEC5C8 N N N N N N N N N N N N N N Y N N N N N N N N N N N N N N N N
> 0000000919AA9558 00000008D7FEC5C8 N N N N N N N N N N N N N N Y N N N N N N N N N N N N N N N N
>
> So why does it only return 5? What about the rest 1021 cursors?
I don't know the exact conditions for SQL statements to appear in v$sql
but not in v$sql_shared_cursor. Possible conditions are
* They're DDLs.
* Part of the cursor optimization info of the SQLs is flushed from library
cache, causing v$sql.optimizer_mode='NONE'
(Ref: )
* They're recursive SQLs.
In your case, that specific SQL may have optmizer_mode='NONE' in v$sql
for most of the 1021 children. If not, see if other columns of v$sql can give a
clue (i.e. compare other columns between the 1021 rows and the 5 rows)
Yong
> You are right. All the remaining optimizer_mode is "NONE".
>
> So does that mean all these cursors' "heap 6" (no clue what that means)
> are flushed?
>
> The question is why so many of them and why isn't the entire child
> cursor aged out?
If optimizer_mode='NONE', then yes their heap 6, which stores execution plans,
is flushed. The reason why not the entire child cursor is flushed may be
related to cursor invalidations; e.g. DDL was run on base objects. (If
somebody flushed shared pool, the entire cursor would be out.)
Can you check those NONE optimizer_mode cursors to see if their last_load_time
differs from first_load_time? It should. What time is it? Does it correspond to
the time of some DDL or ANALYZE job?
Yong
> All the last_load_time are blank and we have no analysis of any kind.
> We still run rule mode. The first load time is when the box was started
> midnight 2 weeks ago.
--------------------------------------------------------------------------------
Commonly used queries against v$sql_shared_cursor when you don't know the address of a specific cursor
/***** 9i version *****/
select a.* from v$sql_shared_cursor a, v$sql b
where a.address = b.child_address
and b.child_number >= 100;
select * from v$sql_shared_cursor where
unbound_cursor || sql_type_mismatch || optimizer_mismatch || outline_mismatch ||
stats_row_mismatch || literal_mismatch || sec_depth_mismatch ||
explain_plan_cursor || buffered_dml_mismatch || pdml_env_mismatch ||
inst_drtld_mismatch || slave_qc_mismatch || typecheck_mismatch ||
auth_check_mismatch || bind_mismatch || describe_mismatch ||
language_mismatch || translation_mismatch || row_level_sec_mismatch ||
insuff_privs || insuff_privs_rem || remote_trans_mismatch ||
logminer_session_mismatch || incomp_ltrl_mismatch || overlap_time_mismatch ||
sql_redirect_mismatch || mv_query_gen_mismatch || user_bind_peek_mismatch ||
typchk_dep_mismatch || no_trigger_mismatch || flashback_cursor like '%Y%';
--Matching on parent address
select * from v$sql where address in
(select kglhdpar from v$sql_shared_cursor where
unbound_cursor || sql_type_mismatch || optimizer_mismatch || outline_mismatch ||
stats_row_mismatch || literal_mismatch || sec_depth_mismatch ||
explain_plan_cursor || buffered_dml_mismatch || pdml_env_mismatch ||
inst_drtld_mismatch || slave_qc_mismatch || typecheck_mismatch ||
auth_check_mismatch || bind_mismatch || describe_mismatch ||
language_mismatch || translation_mismatch || row_level_sec_mismatch ||
insuff_privs || insuff_privs_rem || remote_trans_mismatch ||
logminer_session_mismatch || incomp_ltrl_mismatch || overlap_time_mismatch ||
sql_redirect_mismatch || mv_query_gen_mismatch || user_bind_peek_mismatch ||
typchk_dep_mismatch || no_trigger_mismatch || flashback_cursor like '%Y%'
);
--Matching on child address
select * from v$sql where child_address in
(select address from v$sql_shared_cursor where
unbound_cursor || sql_type_mismatch || optimizer_mismatch || outline_mismatch ||
stats_row_mismatch || literal_mismatch || sec_depth_mismatch ||
explain_plan_cursor || buffered_dml_mismatch || pdml_env_mismatch ||
inst_drtld_mismatch || slave_qc_mismatch || typecheck_mismatch ||
auth_check_mismatch || bind_mismatch || describe_mismatch ||
language_mismatch || translation_mismatch || row_level_sec_mismatch ||
insuff_privs || insuff_privs_rem || remote_trans_mismatch ||
logminer_session_mismatch || incomp_ltrl_mismatch || overlap_time_mismatch ||
sql_redirect_mismatch || mv_query_gen_mismatch || user_bind_peek_mismatch ||
typchk_dep_mismatch || no_trigger_mismatch || flashback_cursor like '%Y%'
);
/***** end for 9i version *****/
/***** 10gR2 version *****/
Differences from 9i:
kglhdpar in 9i changed to address in 10g
address in 9i changed to child_address in 10g
plus much more columns in v$sql_shared_cursor
Note: 10gR1 has more columns than 9i but less than 10gR2
select a.* from v$sql_shared_cursor a, v$sql b
where a.child_address = b.child_address
and b.child_number >= 100;
select * from v$sql_shared_cursor where
unbound_cursor || sql_type_mismatch || optimizer_mismatch || outline_mismatch ||
stats_row_mismatch || literal_mismatch || sec_depth_mismatch ||
explain_plan_cursor || buffered_dml_mismatch || pdml_env_mismatch ||
inst_drtld_mismatch || slave_qc_mismatch || typecheck_mismatch ||
auth_check_mismatch || bind_mismatch || describe_mismatch ||
language_mismatch || translation_mismatch || row_level_sec_mismatch ||
insuff_privs || insuff_privs_rem || remote_trans_mismatch ||
logminer_session_mismatch || incomp_ltrl_mismatch || overlap_time_mismatch ||
sql_redirect_mismatch || mv_query_gen_mismatch || user_bind_peek_mismatch ||
typchk_dep_mismatch || no_trigger_mismatch || flashback_cursor ||
anydata_transformation || incomplete_cursor || top_level_rpi_cursor ||
different_long_length || logical_standby_apply || diff_call_durn ||
bind_uacs_diff || plsql_cmp_switchs_diff || cursor_parts_mismatch ||
stb_object_mismatch || row_ship_mismatch || pq_slave_mismatch ||
top_level_ddl_mismatch || multi_px_mismatch || bind_peeked_pq_mismatch ||
mv_rewrite_mismatch || roll_invalid_mismatch || optimizer_mode_mismatch ||
px_mismatch || mv_staleobj_mismatch || flashback_table_mismatch ||
litrep_comp_mismatch like '%Y%';
--Matching on parent address
select * from v$sql where address in
(select address from v$sql_shared_cursor where
unbound_cursor || sql_type_mismatch || optimizer_mismatch || outline_mismatch ||
stats_row_mismatch || literal_mismatch || sec_depth_mismatch ||
explain_plan_cursor || buffered_dml_mismatch || pdml_env_mismatch ||
inst_drtld_mismatch || slave_qc_mismatch || typecheck_mismatch ||
auth_check_mismatch || bind_mismatch || describe_mismatch ||
language_mismatch || translation_mismatch || row_level_sec_mismatch ||
insuff_privs || insuff_privs_rem || remote_trans_mismatch ||
logminer_session_mismatch || incomp_ltrl_mismatch || overlap_time_mismatch ||
sql_redirect_mismatch || mv_query_gen_mismatch || user_bind_peek_mismatch ||
typchk_dep_mismatch || no_trigger_mismatch || flashback_cursor ||
anydata_transformation || incomplete_cursor || top_level_rpi_cursor ||
different_long_length || logical_standby_apply || diff_call_durn ||
bind_uacs_diff || plsql_cmp_switchs_diff || cursor_parts_mismatch ||
stb_object_mismatch || row_ship_mismatch || pq_slave_mismatch ||
top_level_ddl_mismatch || multi_px_mismatch || bind_peeked_pq_mismatch ||
mv_rewrite_mismatch || roll_invalid_mismatch || optimizer_mode_mismatch ||
px_mismatch || mv_staleobj_mismatch || flashback_table_mismatch ||
litrep_comp_mismatch like '%Y%'
);
--Matching on child address
select * from v$sql where child_address in
(select child_address from v$sql_shared_cursor where
unbound_cursor || sql_type_mismatch || optimizer_mismatch || outline_mismatch ||
stats_row_mismatch || literal_mismatch || sec_depth_mismatch ||
explain_plan_cursor || buffered_dml_mismatch || pdml_env_mismatch ||
inst_drtld_mismatch || slave_qc_mismatch || typecheck_mismatch ||
auth_check_mismatch || bind_mismatch || describe_mismatch ||
language_mismatch || translation_mismatch || row_level_sec_mismatch ||
insuff_privs || insuff_privs_rem || remote_trans_mismatch ||
logminer_session_mismatch || incomp_ltrl_mismatch || overlap_time_mismatch ||
sql_redirect_mismatch || mv_query_gen_mismatch || user_bind_peek_mismatch ||
typchk_dep_mismatch || no_trigger_mismatch || flashback_cursor ||
anydata_transformation || incomplete_cursor || top_level_rpi_cursor ||
different_long_length || logical_standby_apply || diff_call_durn ||
bind_uacs_diff || plsql_cmp_switchs_diff || cursor_parts_mismatch ||
stb_object_mismatch || row_ship_mismatch || pq_slave_mismatch ||
top_level_ddl_mismatch || multi_px_mismatch || bind_peeked_pq_mismatch ||
mv_rewrite_mismatch || roll_invalid_mismatch || optimizer_mode_mismatch ||
px_mismatch || mv_staleobj_mismatch || flashback_table_mismatch ||
litrep_comp_mismatch like '%Y%'
);
/***** end for 10gR2 version *****/
--------------------------------------------------------------------------------
Sometimes v$sql_shared_cursor fails to reveal why cursors are not shared. It's
known that when cursor_sharing=similar, a histogram on a column causes hard
parses (even when the data is not skewed). Test code is from
except for the first SQL (create table). Test is done on 9.2.0.1.0 and
reproduced in 10gR1, 10gR2.
create table t as select rownum id from all_objects;
create index t_idx on t (id);
begin
dbms_stats.gather_table_stats
( ownname => USER,
tabname => 'T',
method_opt => 'for all indexed columns size 254',
cascade => TRUE
);
end;
/
alter session set cursor_sharing=similar;
select * from t CS_SIMILAR where id = 1;
select * from t CS_SIMILAR where id = 50;
select * from t CS_SIMILAR where id = 99;
select * from t CS_SIMILAR where id = 1;
select * from t CS_SIMILAR where id = 50;
select * from t CS_SIMILAR where id = 99;
select sql_text from v$sql where sql_text like 'select * from t CS% where id = %' order by sql_text;
The last query does show 3 rows:
SQL_TEXT
------------------------------------------------
select * from t CS_SIMILAR where id = :"SYS_B_0"
select * from t CS_SIMILAR where id = :"SYS_B_0"
select * from t CS_SIMILAR where id = :"SYS_B_0"
As usual, I want to see why the same SQL is not shared (change kglhdpar to address in 10g; my address '7911C6A0' is from v$sql.address):
SQL> select * from v$sql_shared_cursor where kglhdpar = '7911C6A0';
ADDRESS KGLHDPAR U S O O S L S E B P I S T A B D L T R I I R L I O S M U T N F
-------- -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
7911C184 7911C6A0 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N
7910BF7C 7911C6A0 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N
7910BA00 7911C6A0 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N
You see, none of the "reason for not sharing" columns is 'Y'. If I look at the plan (select * from v$sql_plan where address = '7911C6A0'), I see 3 rows with no difference except, of course, under child_number.
This means it doesn't matter whether the data is skewed or not. If you have a histogram, a different SQL child cursor is created (i.e. a hard parse happens). Unfortunately, v$sql_shared_cursor fails to tell us why the sibling cursors are not one single cursor.
I realized that I actually read the same conclusion in Jonathan Lewis's "Cost-Based Oracle" earlier. On p.159 of his book, he says "two things will trigger this reoptimization [when cursor_sharing=similar]: first, if any of the predicates involves a range scan, and second, even on a simple equality, if there is histogram on a column that appears in a predicate, the query will be reoptimized." In my test case, both conditions are met, although just the second condition is enough (as in biti's test at blog.csdn.net/biti_rainy/archive/2004/07/12/39466.aspx).
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/1933/viewspace-907536/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- v$sql_shared_cursor中的BIND_MISMATCHSQL
- V$SQL_SHARED_CURSOR檢視硬解析的原因SQL
- v$sql v$sqlarea v$sql_shared_cursor及遊標SQL
- v$sql_shared_cursor檢視記錄多版本的資訊SQL
- 【CURSOR】Oracle 子游標無法共享的原因之V$SQL_SHARED_CURSOROracleSQL
- cursor_sharing與v$sqlarea_v$sql_v$sql_shared_cursorSQL
- v$sql v$sqlarea v$sql_shared_cursor及父遊標,子游標SQL
- sql執行計劃_v$sqlarea_v$sql_v$sql_shared_cursorSQL
- 檢視v$sql_shared_cursor檢視獲取sql語句為什麼不能共享?SQL
- IsPostBack深入探討(轉轉轉轉轉)
- 玩轉SSH埠轉發
- 彼得反轉原理(轉載)
- java 跳轉語句(轉)Java
- JDom 常用轉換方法 (轉)
- 行列轉換 交叉表 (轉)
- Excel轉PDF怎麼轉?Excel轉PDF方法有哪些Excel
- 語音轉文字工具,語音轉文字怎樣轉?
- 什麼是SSH埠轉發(本地轉發、遠端轉發、動態轉發)?
- SQL 行轉列,列轉行SQL
- (轉)OC專案轉Swift指南Swift
- pdf轉word如何線上轉換?
- 轉轉OLAP自助分析實踐
- JS轉換HTML轉義符JSHTML
- (轉)SqlServer裡DateTime轉字串SQLServer字串
- Mysql - 行轉列、列轉行MySql
- js跳轉頁面方法(轉)JS
- oracle行列轉換-行轉列Oracle
- oracle行列轉換-列轉行Oracle
- 內碼轉換技術 (轉)
- 金額大寫轉換(轉)
- | / - 的旋轉效果實現(轉)
- 【轉】ckEditor使用方法 轉帖
- 從C轉入C++ (轉)C++
- svg 至 flash的轉化 (轉)SVG
- 玩轉Windows桌面圖示 (轉)Windows
- 大寫金額轉換 (轉)
- 用Javascript轉換原始碼 (轉)JavaScript原始碼
- 玩轉網頁捲軸(轉)網頁