ITPub博客

首页 > 数据库 > Oracle > cursor_sharing的测试

cursor_sharing的测试

原创 Oracle 作者:haochunpeng 时间:2007-01-30 22:54:32 0 删除 编辑

众所周知,cursor_sharing=force可以在数据库端强行绑定变量,以减少shared pool latch 和 cpu 的压力。
但通过下面的测试,发现这个参数的设置不是任何环境下都有用的:

[@more@]


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/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
  • 博文量
    19
  • 访问量
    254808