绑定变量

来源:互联网 发布:风云无双天劫进阶数据 编辑:程序博客网 时间:2024/06/06 07:30
在开发中,如果不使用绑定变量,会给系统带来灾难性的后果,因为我们写的每一条sql都会经过解析,但是这个过程很占用cpu,解析过得sql 会放在共享池的Library Cache里,如果不使用绑定变量的话,每一条sql都会解析一次(硬解析),不会被重复使用,这样会大大降低oracle的性能。使用绑定变量,sql语句只会解析一次(软解析)。
下面通过列子说明使用和不使用绑定变量给系统带来的性能问题:
SQL> select * from v$version where rownum<2;


BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production


SQL> show user;
USER 为 "HR"
SQL> create table t(a varchar2(10),b varchar2(10));
表已创建。
不使用绑定变量
我们向该表中插入五条数据:
SQL> set timing on;
SQL>  declare
  2   m  varchar2(400);
  3   begin
  4   for i  in 1 .. 5
  5   loop
  6   m := 'insert into t(a,b) values('||to_char(i)||','||to_char(i+1)||')';
  7   execute immediate m;
  8   end loop;
  9   end;
 10  /
PL/SQL 过程已成功完成。
已用时间:  00: 00: 00.13
使用绑定变量
 SQL> set timing on;
SQL>  declare
  2   m  varchar2(400);
  3   begin
  4   for i  in 1 .. 5
  5   loop
  6   m := 'insert into t(a,b) values(:1,:2)';
  7   execute immediate m using i,i+1;
  8   end loop;
  9   end;
 10  /
PL/SQL 过程已成功完成。
已用时间:  00: 00: 00.01
上面的pl/sql过程执行了两次
通过时间也许我们还不能说明绑定变量的高效,下面我们通过v$sql视图查看执行的sql语句:

通过上面截图,发现了没有,绑定变量被调用了10次,只解析一次。
如果一项工程,没有用绑定变量,无疑这是灾难性的,oracle提供了强制把所有的sql转换成绑定变量,把参数cursor_sharing改为force即可,但是这很容易造成bug:
SQL> show parameter cursor;


NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
cursor_sharing                       string      EXACT
cursor_space_for_time                boolean     FALSE
open_cursors                         integer     300
session_cached_cursors               integer     50
SQL> show parameter cursor_sharing;


NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
cursor_sharing                       string      EXACT
Cursor_sharing参数有3个值可以设置:
EXACT:通常来说,exact值是Oracle推荐的,也是默认的,它要求SQL语句在完全相同时才会重用,否则会被重新执行硬解析操作
SIMILAR:similar是在Oracle认为某条SQL语句的谓词条件可能会影响到它的执行计划时,才会被重新分析,否则将重用SQL
FORCE:force是在任何情况下,无条件重用SQL
注意:上面所说的SQL重用,仅仅是指谓词条件不同的SQL语句,实际上这样的SQL基本上都在执行同样的业务操作
这方面涉及到了oracle中的cursor对象,该对象在oracle十分重要。用户进程的任务执行以及Cursor的使用是PGA内存的主要消耗者,
是我们进行数据库性能优化最关心的内容,事实上数据库的活动主要就是Cursor的活动。
0 0