数据库高效优化:架构、规范与SQL技巧
上QQ阅读APP看书,第一时间看更新

6.3 游标共享

游标是否共享是通过参数cursor_sharing来控制的。下面分别说明这个参数几种取值的含义。

·EXACT:只有当发布的SQL语句与缓存中的语句完全相同时才用已有的执行计划。

·FORCE:如果SQL语句是字面量,则迫使优化器始终使用已有的执行计划。(无论已有的执行计划是不是最佳的。)优化器将把SQL语句所有字面常量替换为系统产生的绑定变量,并检查是否存在一个以前产生的共享游标用于修改后的语句。

·SIMILAR:如果SQL语句是字面量,则只有当已有的执行计划是最佳时才使用它,如果已有执行计划不是最佳,则重新对这个SQL语句进行分析以制定最佳执行计划。首先将字面变量替换为绑定变量,然后窥视绑定变量的值。如果有必要,将对该语句每次单独的分析调用中输入值进行优化。该参数指定Oracle在存在柱状图信息时,对于不同的变量值,重新解析,从而利用柱状图更为精确地指定SQL执行计划。即当存在柱状图时,SIMILAR的表现和EXACT一样;当不存在柱状图时,SIMILAR的表现和FORCE相同。

下面通过一个例子说明。


create table t1 as select rownum id ,object_name name from sys.dba_objects;

show parameter cursor_sharing=> FORCE

select * from t1 where id=1;

selectsql_text,sql_id,version_count,executions
fromv$sqlarea
wheresql_text like 'select * from t1%';
SQL_TEXT                                 SQL_ID        VERSION_COUNT EXECUTIONS
---------------------------------------- ------------- ------------- ----------
select * from t1 where id=:"SYS_B_0"     6800d8tpghk0c             1          1
//在CURSOR_SHARING为FORCE的情况下,Oracle强制使用了绑定变量,甚至直接改写了SQL

alter session set cursor_sharing=EXACT;

grant select on t1 to sys;
//通过这种方式淘汰了已经生成的执行计划

select * from t1 where id=1;

select sql_text,sql_id,version_count,executions
from v$sqlarea
where sql_text like 'select * from t1%';
SQL_TEXT                                 SQL_ID        VERSION_COUNT EXECUTIONS
---------------------------------------- ------------- ------------- ----------
select * from t1 where id=1              5ag8kthgnvjk2             1          1
/*
再次执行上面的SQL,可见在CURSOR_SHARING=EXACT的情况下,绝对精确匹配文本,没有使用绑定变量
*/