在开发中,如果不使用绑定变量,会给系统带来灾难性的后果,因为我们写的每一条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的活动。
下面通过列子说明使用和不使用绑定变量给系统带来的性能问题:
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的活动。