ORACLE绑定变量的使用
2015-11-24 15:34
441 查看
转自:http://www.cnblogs.com/HondaHsu/archive/2008/12/17/1356444.html
在ORACLE中,使用绑定变量,可以降低硬解析,通常可以提高系统的性能(注意,是通常,不是任何情况下)。
以表tabletest为例,我们来看看如何使用绑定变量,tabletest的表结构为 field1 number(10) field2 number(10) field3 number(10) field4 number(10) field5 number(10) 绑定变量可以理解为一个占位符 ,例如:declare i number; j number; sqlstr varchar2(200);begin i:=1; j:=2; sqlstr:='insert into 测试表 (field1,field2,field3,field4,field5) values(:x,:x,:y,:x,:x)';
execute immediate sqlstr using i,i,j,i,i;
这样的一段代码中,使用i,i,j,i,i来对应:x,:x,:y,:x,:x。这段代码是正确的,但如果以为sqlstr中只有:x,:y这两个绑定变量,而把语句execute immediate sqlstr using i,i,j,i,i;改为execute immediate sqlstr using i,j;就会在运行中出现绑定变量数量不够的错误。上面的正确代码执行完后,插入的记录从field1到field5的数据应该是1,1,2,1,1。如果我们把execute immediate sqlstr using i,i,j,i,i;改成execute immediate sqlstr using i,j,j,i,i;执行之后,察看插入的记录,就会发现插入的记录是1,2,2,1,1从上面可以看出,绑定变量只是起到占位的作用,同名的绑定变量并不意味着在它们是同样的,在传递时要考虑的是传递的值与绑定变量出现顺序的对位,而不是绑定变量的名称。ORACLE系统本身是能够对变量做绑定的,例如下面的代码:declare i number;begin for i in 1..1000 loop insert into 测试表 (i,i+1,i*1,i*2,i-1) end loop;end;这段代码是不需要使用绑定变量的方法来提高效率的,ORACLE会自动将其中的变量绑定。我们可以这样理解:这段代码执行了1000次的 insert into 测试表 (i,i+1,i*1,i*2,i-1) 语句,每次发出去的语句都是一样的。如果把这段代码改成如下:declare i number; sqlstr varchar2(200);begin for i in 1..1000 loop sqlstr:='insert into 测试表 ('||to_char(i)||','||to_char(i)||'+1,'||to_char(i)||'*1,'||to_char(i)||'*2,'||to_char(i)||'-1) '; execute immediate sqlstr; end loop;end;这段代码同样是执行了1000条insert语句,但是每一条语句都是不同的,因此ORACLE会把每条语句硬解析一次,其效率就比前面那段就低得多了。如果要提高效率,不妨使用绑定变量将循环中的语句改为 sqlstr:='insert into 测试表 (:i,:i+1,:i*1,:i*2,:i-1) '; execute immediate sqlstr using i,i,i,i,i;这样执行的效率就高得多了。我曾试着使用绑定变量来代替表名、过程名、字段名等,结果是语句错误,结论就是绑定变量不能当作嵌入的字符串来使用,只能当作语句中的变量来用。从效率来看,由于oracle10G放弃了RBO,全面引入CBO,因此,在10G中使用绑定变量效率的提升比9i中更为明显。最后,前面说到绑定变量是在通常情况下能提升效率,那哪些是不通常的情况呢?答案是:在字段(包括字段集)建有索引,且字段(集)的集的势非常大(也就是有个值在字段中出现的比例特别的大)的情况下,使用绑定变量可能会导致查询计划错误,因而会使查询效率非常低。这种情况最好不要使用绑定变量。
在ORACLE中,使用绑定变量,可以降低硬解析,通常可以提高系统的性能(注意,是通常,不是任何情况下)。
以表tabletest为例,我们来看看如何使用绑定变量,tabletest的表结构为 field1 number(10) field2 number(10) field3 number(10) field4 number(10) field5 number(10) 绑定变量可以理解为一个占位符 ,例如:declare i number; j number; sqlstr varchar2(200);begin i:=1; j:=2; sqlstr:='insert into 测试表 (field1,field2,field3,field4,field5) values(:x,:x,:y,:x,:x)';
execute immediate sqlstr using i,i,j,i,i;
end;
这样的一段代码中,使用i,i,j,i,i来对应:x,:x,:y,:x,:x。这段代码是正确的,但如果以为sqlstr中只有:x,:y这两个绑定变量,而把语句execute immediate sqlstr using i,i,j,i,i;改为execute immediate sqlstr using i,j;就会在运行中出现绑定变量数量不够的错误。上面的正确代码执行完后,插入的记录从field1到field5的数据应该是1,1,2,1,1。如果我们把execute immediate sqlstr using i,i,j,i,i;改成execute immediate sqlstr using i,j,j,i,i;执行之后,察看插入的记录,就会发现插入的记录是1,2,2,1,1从上面可以看出,绑定变量只是起到占位的作用,同名的绑定变量并不意味着在它们是同样的,在传递时要考虑的是传递的值与绑定变量出现顺序的对位,而不是绑定变量的名称。ORACLE系统本身是能够对变量做绑定的,例如下面的代码:declare i number;begin for i in 1..1000 loop insert into 测试表 (i,i+1,i*1,i*2,i-1) end loop;end;这段代码是不需要使用绑定变量的方法来提高效率的,ORACLE会自动将其中的变量绑定。我们可以这样理解:这段代码执行了1000次的 insert into 测试表 (i,i+1,i*1,i*2,i-1) 语句,每次发出去的语句都是一样的。如果把这段代码改成如下:declare i number; sqlstr varchar2(200);begin for i in 1..1000 loop sqlstr:='insert into 测试表 ('||to_char(i)||','||to_char(i)||'+1,'||to_char(i)||'*1,'||to_char(i)||'*2,'||to_char(i)||'-1) '; execute immediate sqlstr; end loop;end;这段代码同样是执行了1000条insert语句,但是每一条语句都是不同的,因此ORACLE会把每条语句硬解析一次,其效率就比前面那段就低得多了。如果要提高效率,不妨使用绑定变量将循环中的语句改为 sqlstr:='insert into 测试表 (:i,:i+1,:i*1,:i*2,:i-1) '; execute immediate sqlstr using i,i,i,i,i;这样执行的效率就高得多了。我曾试着使用绑定变量来代替表名、过程名、字段名等,结果是语句错误,结论就是绑定变量不能当作嵌入的字符串来使用,只能当作语句中的变量来用。从效率来看,由于oracle10G放弃了RBO,全面引入CBO,因此,在10G中使用绑定变量效率的提升比9i中更为明显。最后,前面说到绑定变量是在通常情况下能提升效率,那哪些是不通常的情况呢?答案是:在字段(包括字段集)建有索引,且字段(集)的集的势非常大(也就是有个值在字段中出现的比例特别的大)的情况下,使用绑定变量可能会导致查询计划错误,因而会使查询效率非常低。这种情况最好不要使用绑定变量。
相关文章推荐
- 查看oracle中被锁的对象
- Oracle密码过期
- ORACLE锁机制深入理解
- oracle个人总结
- Oracle trunc()函数的用法
- ORACLE SQL性能优化系列 (二)
- ORACLE SQL性能优化系列 (三)
- ORACLE SQL性能优化系列 (一)
- Oracle nvl(),nvl2()函数介绍
- ORACLE中SQL查询优化研究
- 更改oracle字符集
- Oracle 300问
- Oracle之常用FAQ--SQL
- Oracle之常用FAQ--性能调整
- oracle查询表空间的空间占用情况
- Oracle之常用FAQ--备份与恢复
- Oracle之常用FAQ--Oracle 构架体系
- Oracle中临时表的深入研究
- Oracle视图和用户管理
- Oracle TYPE OBJECT 用法