首页 > 数据库 > Oracle > cursor_sharing的测试
众所周知,cursor_sharing=force可以在数据库端强行绑定变量,以减少shared pool latch 和 cpu 的压力。
但通过下面的测试,发现这个参数的设置不是任何环境下都有用的:
1、sql语句的测试
SQL> select sql_text from v$sql where sql_text like 'select /* abc */ %';
未选定行
SQL> select /* abc */ username from all_users where rownum = 1;
USERNAME
------------------------------------------------------------
SYS
SQL> select sql_text from v$sql where sql_text like 'select /* abc */ %';
SQL_TEXT
----------------------------------------------------------
select /* abc */ username from all_users where rownum = 1
SQL> alter session set cursor_sharing=force;
会话已更改。
SQL> select /* abc */ username from all_users where rownum = 2;
未选定行
SQL> select sql_text from v$sql where sql_text like 'select /* abc */ %';
SQL_TEXT
----------------------------------------------------------------------
select /* abc */ username from all_users where rownum = :"SYS_B_0"
select /* abc */ username from all_users where rownum = 1
SQL> select /* abc */ username from all_users where rownum = 3;
未选定行
SQL> select sql_text from v$sql where sql_text like 'select /* abc */ %';
SQL_TEXT
----------------------------------------------------------------------
select /* abc */ username from all_users where rownum = :"SYS_B_0"
select /* abc */ username from all_users where rownum = 1
可以看到,在sqlplus里面执行sql语句,cursor_sharing=force还是起作用的,oracle强制对sql进行绑定变量。
2、plsql的测试
--绑定变量的plsql
create or replace procedure proc1
as
v_i int;
begin
for i in 1..10000
loop
execute immediate 'select x from test where x = :x' into v_i using i;
end loop;
end;
--没有绑定变量的plsql
create or replace procedure proc2
as
v_i int;
begin
for i in 1..10000
loop
execute immediate 'select x from test where x = '||i;
end loop;
end;
下面测试:
--测试session的sid是14
SQL> select distinct sid from v$Mystat;
SID
----------
14
--从另一个sqlplus执行如下sql,查看解析的情况
SQL> select st.name,se.VALUE from v$sesstat se,v$statname st
2 where se.STATISTIC#=st.STATISTIC# and st.STATISTIC# between 232 and 233 and se.sid = 14;
NAME VALUE
------------------------------ ----------
parse count (total) 4
parse count (hard) 1
--测试session开始执行proc1,这个是绑定变量的过程;
SQL> exec proc1;
PL/SQL 过程已成功完成。
--查看其解析的情况
SQL> l
1 select st.name,se.VALUE from v$sesstat se,v$statname st
2* where se.STATISTIC#=st.STATISTIC# and st.STATISTIC# between 232 and 233 and se.sid = 14
SQL> /
NAME VALUE
------------------------------ ----------
parse count (total) 10022
parse count (hard) 3
--重新登录sqlplus,并执行proc2,这个是没有绑定变量的过程。
SQL> exit
从 Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.1.0 - Production 断开
C:>sqlplus / as sysdba
SQL*Plus: Release 10.2.0.1.0 - Production on 星期二 1月 30 22:41:04 2007
Copyright (c) 1982, 2005, Oracle. All rights reserved.
连接到:
Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.1.0 - Production
SQL> exec proc2;
PL/SQL 过程已成功完成。
--查看其解析的情况
SQL> l
1 select st.name,se.VALUE from v$sesstat se,v$statname st
2* where se.STATISTIC#=st.STATISTIC# and st.STATISTIC# between 232 and 233 and se.sid = 14
SQL> /
NAME VALUE
------------------------------ ----------
parse count (total) 10015
parse count (hard) 10001
比较2个程序执行后解析的情况,很显然,在程序中绑定变量,会有效的降低硬解析。
但是如果在执行proc2之前设置参数cursor_sharing=force,是否能强制绑定变量呢?
SQL> l
1 select st.name,se.VALUE from v$sesstat se,v$statname st
2* where se.STATISTIC#=st.STATISTIC# and st.STATISTIC# between 232 and 233 and se.sid = 14
SQL> /
NAME VALUE
------------------------------ ----------
parse count (total) 10032
parse count (hard) 10008
答案是不可以,看来cursor_sharing=force也不是在任何情况都有用的,而且设置这个参数在某些版本上还会触发bug。
所以最好的情况还是在应用程序中,绑定变量。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/19015/viewspace-896236/ ,如需转载,请注明出处,否则将追究法律责任。