您的位置:首页 > 其它

初始化参数之cursor_sharing

2013-01-21 15:17 405 查看
一、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));

Table created.

----产生一些数据----
5 SQL> insert into jack values(1,'aa');

1 row created.

SQL> insert into jack values(2,'bb');

1 row created.

SQL> insert into jack values(3,'cc');

1 row created.

SQL> insert into jack values(4,'dd');

1 row created.

SQL> commit;

Commit complete.

SQL> select * from jack;

ID NAME
---------- ----------
1 aa
2 bb
3 cc
4 dd

----创建下面实验将要用到的三张表----
34 SQL> create table jack_exact as select * from jack;

Table created.

SQL> create table jack_similar as select * from jack;

Table created.

SQL> create table jack_force as select * from jack;

Table created.

----查看该session的trace文件的路径----
46 SQL> @/u01/scripts/showtrace

trace_file_name
--------------------------------------------------------------------------------
/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;

Session altered.

SQL> alter session set sql_trace=true;

Session altered.

SQL> select * from jack_exact where id=1;

ID NAME
---------- ----------
1 aa

SQL> select * from jack_exact where id=3;

ID NAME
---------- ----------
3 cc

21 SQL> select * from jack_exact where id=1;

ID NAME
---------- ----------
1 aa

SQL> alter session set sql_trace=false;

Session altered.

----从下面的查询可以看出执行了两次硬解析----
31 SQL> select sql_text from v$sql where sql_text like 'select * from jack_exact where%';

SQL_TEXT
--------------------------------------------------------------------------------
select * from jack_exact where id=1
select * from jack_exact where id=3

----查看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
Plan Hash: 4127630146
select *
from
jack_exact where id=1

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          1          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        2      0.00       0.00          0          4          0           1
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        4      0.00       0.00          0          5          0           1

Misses in library cache during parse: 1    ---id=1,执行一次硬解析
Optimizer mode: ALL_ROWS
Parsing user id: 105

Rows     Row Source Operation
-------  ---------------------------------------------------
1  TABLE ACCESS FULL JACK_EXACT (cr=4 pr=0 pw=0 time=0 us cost=3 size=20 card=1)

********************************************************************************

SQL ID: 1n0paamkf7sup
Plan Hash: 4127630146
select *
from
jack_exact where id=3

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          1          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        2      0.00       0.00          0          4          0           1
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        4      0.00       0.00          0          5          0           1

Misses in library cache during parse: 1     ----id=3,执行一次硬解析
Optimizer mode: ALL_ROWS
Parsing user id: 105

Rows     Row Source Operation
-------  ---------------------------------------------------
1  TABLE ACCESS FULL JACK_EXACT (cr=4 pr=0 pw=0 time=0 us cost=3 size=20 card=1)

********************************************************************************

SQL ID: fnggytkynxz04
Plan Hash: 4127630146
select *
from
jack_exact where id=1

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        2      0.00       0.00          0          4          0           1
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        4      0.00       0.00          0          4          0           1

Misses in library cache during parse: 0   ----执行一次软解析
Optimizer mode: ALL_ROWS
Parsing user id: 105

Rows     Row Source Operation
-------  ---------------------------------------------------
1  TABLE ACCESS FULL JACK_EXACT (cr=4 pr=0 pw=0 time=0 us cost=3 size=20 card=1)

********************************************************************************

总结:当cursor_sharing=exact时,只有当SQL语句是完全一样的情况下才能被重用。
2.3 cursor_sharing=similar的情况:

----将curor_sharing设置为similar----
1 SQL> alter session set cursor_sharing=similar;

Session altered.

SQL> alter session set sql_trace=true;

Session altered.

SQL> select * from jack_similar where id=1;

ID NAME
---------- ----------
1 aa

SQL> select * from jack_similar where id=4;

ID NAME
---------- ----------
4 dd

SQL> select * from jack_similar where id=8;

no rows selected

----下面查询中可以看到Oracle将SQL中的谓词条件用同一个名词的一个变量替代,尽管看起来是一样的,但是Oracle依然把它们作为两条SQL来处理----
25 SQL> select sql_text from v$sql where sql_text like 'select * from jack_similar where%';

SQL_TEXT
--------------------------------------------------------------------------------
select * from jack_similar where id=:"SYS_B_0"
select * from jack_similar where id=:"SYS_B_0"
select * from jack_similar where id=:"SYS_B_0"

SQL> alter session set sql_trace=false;

Session altered.

[oracle@yft ~]$ tkprof /u01/app/oracle/diag/rdbms/yft/yft/trace/yft_ora_5329.trc out.txt  sys=no

TKPROF: Release 11.2.0.1.0 - Development on Tue Jan 22 10:18:16 2013

Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.

----从trace文件中可以清楚看到上面的结论----
43 SQL ID: 80chtmbbwpx49
Plan Hash: 1559066762
select *
from
jack_similar where id=:"SYS_B_0"

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        3      0.00       0.00          0          0          0           0
Execute      3      0.00       0.00          0          3          0           0
Fetch        5      0.00       0.00          0         10          0           2
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total       11      0.01       0.01          0         13          0           2

Misses in library cache during parse: 3    ----进行三次查询,都各执行了一次硬解析。
Optimizer mode: ALL_ROWS
Parsing user id: 105

Rows     Row Source Operation
-------  ---------------------------------------------------
1  TABLE ACCESS FULL JACK_SIMILAR (cr=4 pr=0 pw=0 time=0 us cost=3 size=20 card=1)

********************************************************************************


对于SIMILAR的情况,如果CBO发现被绑定变量的谓词还有其他的执行计划可以选择时,如果谓词条件的值有变化,就将会产生一个新的子游标,而不是重用之前的SQL;如果谓词没有其他的执行计划可选择,则忽略谓词的值,重用之前的SQL。
上面的例子还不能足以说明该情况,接着下面的模拟:

----清楚一下shared_pool中的内容,否则会影响后面的输出----
1 SQL> alter system flush shared_pool;

System altered.

SQL> select * from jack_similar;

ID NAME
---------- ----------
1 aa
2 bb
3 cc
4 dd

SQL> insert into jack_similar values(1,'gg');

1 row created.

SQL> commit;

Commit complete.

----创建索引,并进行分析----
22 SQL> create index jack_similar_ind on jack_similar(id);

Index created.
SQL> exec dbms_stats.gather_table_stats(user,'jack_similar',cascade=>true);

PL/SQL procedure successfully completed.

SQL> select * from jack_similar;

ID NAME
---------- ----------
1 aa
2 bb
3 cc
4 dd
1 gg

SQL> alter session set cursor_sharing=similar;

Session altered.

SQL> alter session set sql_trace=true;

Session altered.

SQL> select * from jack_similar where id=1 and name='aa';

ID NAME
---------- ----------
1 aa

SQL> select * from jack_similar where id=1 and name='gg';

ID NAME
---------- ----------
1 gg

SQL> alter session set sql_trace=false;

Session altered.

----在这里可以看到执行两次SQL查询,只进行了一个硬解析----
63 SQL> select sql_text from v$sql where sql_text like 'select * from jack_similar where%';

SQL_TEXT
--------------------------------------------------------------------------------
select * from jack_similar where id=:"SYS_B_0" and name=:"SYS_B_1"

----在trace文件也验证了这一点。----
----虽然name的值发生了改变,但是id的值没有发生变,而id上有索引的,name上没有索引,CBO认为这样的情况不会改变SQL的执行计划。
70 SQL ID: 10ku2kuy1sqaj
Plan Hash: 2730352089
select *
from
jack_similar where id=:"SYS_B_0" and name=:"SYS_B_1"

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        2      0.00       0.00          0          4          0           1
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        4      0.00       0.00          0          4          0           1

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 105

Rows     Row Source Operation
-------  ---------------------------------------------------
1  TABLE ACCESS BY INDEX ROWID JACK_SIMILAR (cr=4 pr=0 pw=0 time=0 us cost=3 size=6 card=1)
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)

********************************************************************************

SQL ID: 10ku2kuy1sqaj
Plan Hash: 2730352089
select *
from
jack_similar where id=:"SYS_B_0" and name=:"SYS_B_1"

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        2      0.00       0.00          0          4          0           1
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        4      0.00       0.00          0          4          0           1

Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: 105

Rows     Row Source Operation
-------  ---------------------------------------------------
1  TABLE ACCESS BY INDEX ROWID JACK_SIMILAR (cr=4 pr=0 pw=0 time=0 us cost=3 size=6 card=1)
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)

********************************************************************************


2.4 cursor_sharing=force的情况

----设置cursor_sharing=force----
1 SQL> alter session set cursor_sharing=force;

Session altered.

SQL> alter session set sql_trace=true;

Session altered.

SQL> select * from jack_force where id=1;

ID NAME
---------- ----------
1 aa

SQL> select * from jack_force where id=4;

ID NAME
---------- ----------
4 dd

SQL> select * from jack_force where id=1;

ID NAME
---------- ----------
1 aa

SQL> alter session set sql_trace=false;

Session altered.

----从下面的查询中可以看出只进行了一次硬解析,而且使用了绑定变量----
31 SQL> select sql_text from v$sql where sql_text like 'select * from jack_force where%';

SQL_TEXT
--------------------------------------------------------------------------------
select * from jack_force where id=:"SYS_B_0"

----查看trace文件内容----
38 [oracle@yft ~]$ tkprof /u01/app/oracle/diag/rdbms/yft/yft/trace/yft_ora_5551.trc  aggregate=no sys=no

SQL ID: 38vy9d4quwdwk
Plan Hash: 1272021682
select *
from
jack_force where id=:"SYS_B_0"

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.01       0.01          0          1          0           0
Execute      1      0.00       0.00          0          1          0           0
Fetch        2      0.00       0.00          0          4          0           1
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        4      0.01       0.01          0          6          0           1

Misses in library cache during parse: 1     ----id=1的时候进行一次硬解析
Optimizer mode: ALL_ROWS
Parsing user id: 105

Rows     Row Source Operation
-------  ---------------------------------------------------
1  TABLE ACCESS FULL JACK_FORCE (cr=4 pr=0 pw=0 time=0 us cost=3 size=20 card=1)

********************************************************************************

SQL ID: 38vy9d4quwdwk
Plan Hash: 1272021682
select *
from
jack_force where id=:"SYS_B_0"

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        2      0.00       0.00          0          3          0           1
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        4      0.00       0.00          0          3          0           1

Misses in library cache during parse: 0     ----id=4的时候进行0次硬解析,一次软解析
Optimizer mode: ALL_ROWS
Parsing user id: 105

Rows     Row Source Operation
-------  ---------------------------------------------------
1  TABLE ACCESS FULL JACK_FORCE (cr=3 pr=0 pw=0 time=0 us cost=3 size=20 card=1)

********************************************************************************

SQL ID: 38vy9d4quwdwk
Plan Hash: 1272021682
select *
from
jack_force where id=:"SYS_B_0"

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        2      0.00       0.00          0          4          0           1
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        4      0.00       0.00          0          4          0           1

Misses in library cache during parse: 0    ----id=1时进行0次硬解析,一次软解析
Optimizer mode: ALL_ROWS
Parsing user id: 105

Rows     Row Source Operation
-------  ---------------------------------------------------
1  TABLE ACCESS FULL JACK_FORCE (cr=4 pr=0 pw=0 time=0 us cost=3 size=20 card=1)

********************************************************************************
总结:force是在任何情况下,无条件重用SQL。


三、总结:

FORCE和SIMIALR最大的区别在于,FORCE会把所有的谓词用变量代替,并且不管变量的值如何,一律重用第一条SQL语句,而SIMILAR会根据谓词的不同,来重新选择SQL的执行计划。

如果一个系统,它存在变量绑定的问题,并且这种问题已经影响到了系统的性能,这时候可以考虑将参数cursor_sharing的值设置为SIMILAR或FORCE来改善这种局面,不过在改成SIMILAR或FORCE都可能带来一些Bug以及很多未知的东西,所以需要慎用。

最后需要说明一点,对于OLTP系统,如果绑定变量情况不好的话,也许可以考虑通过设置这个参数来缓解一下问题;对于是在OLAP系统上,这个参数应该设置成EXACT,并且不应该使用绑定变量,因为在OLAP系统中,SQL的解析对于SQL的执行来看,话费的代价几乎可以忽略,而正确的SQL执行计划才是OLAP数据库最需要关注的。

四、引用Reference

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: