上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的情况下,绝对精确匹配文本,没有使用绑定变量 */