初始化参数之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 创建实验环境:
2.2 cursor_sharing=exact的情况:
总结:当cursor_sharing=exact时,只有当SQL语句是完全一样的情况下才能被重用。
2.3 cursor_sharing=similar的情况:
对于SIMILAR的情况,如果CBO发现被绑定变量的谓词还有其他的执行计划可以选择时,如果谓词条件的值有变化,就将会产生一个新的子游标,而不是重用之前的SQL;如果谓词没有其他的执行计划可选择,则忽略谓词的值,重用之前的SQL。
上面的例子还不能足以说明该情况,接着下面的模拟:
2.4 cursor_sharing=force的情况
三、总结:
FORCE和SIMIALR最大的区别在于,FORCE会把所有的谓词用变量代替,并且不管变量的值如何,一律重用第一条SQL语句,而SIMILAR会根据谓词的不同,来重新选择SQL的执行计划。
如果一个系统,它存在变量绑定的问题,并且这种问题已经影响到了系统的性能,这时候可以考虑将参数cursor_sharing的值设置为SIMILAR或FORCE来改善这种局面,不过在改成SIMILAR或FORCE都可能带来一些Bug以及很多未知的东西,所以需要慎用。
最后需要说明一点,对于OLTP系统,如果绑定变量情况不好的话,也许可以考虑通过设置这个参数来缓解一下问题;对于是在OLAP系统上,这个参数应该设置成EXACT,并且不应该使用绑定变量,因为在OLAP系统中,SQL的解析对于SQL的执行来看,话费的代价几乎可以忽略,而正确的SQL执行计划才是OLAP数据库最需要关注的。
四、引用Reference
这个参数是用来告诉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
相关文章推荐
- 初始化参数之cursor_sharing
- 初始化参数之cursor_sharing
- [转]Oracle 初始化参数之cursor_sharing
- Oracle cursor_sharing 参数 详解
- 参数cursor_sharing的值
- Oracle cursor_sharing 参数 详解
- Oracle cursor_sharing 参数 详解
- Oracle初始化参数CURSOR_SHARING详解
- 在oracle 10g下,outline(存储大纲)与cursor_sharing参数的依赖关系
- Oracle cursor_sharing 参数 详解
- Oracle cursor_sharing 参数 详解
- Oracle cursor_sharing 参数 详解
- Oracle cursor_sharing 参数 详解
- Oracle cursor_sharing 参数 详解
- Oracle cursor_sharing 参数 详解
- Oracle cursor_sharing 参数 详解
- Oracle cursor_sharing 参数 详解
- Oracle cursor_sharing 参数 详解
- cursor_sharing 参数
- Oracle cursor_sharing 参数 详解