关于绑定变量

来源:互联网 发布:人工智能课程设计实例 编辑:程序博客网 时间:2024/06/15 05:23
应用程序方面
(1)从应用程序角度,如果使用PL/SQL来编程,使用绑定变量就会更加简单。
(2)如果使用JDBC来开发,不适用绑定变量会使SQL语句更加简单。




性能方面
(1)优点
可以在库缓存中共享游标,这样可以避免硬解析以及与之相关额外的开销。但这种情况并不是绝对的。
例:
n number;
v varchar2(32);


--第一次执行
n:=1;v:='first';
insert into t(n,v) values(:n,:v);


--第二次执行
n:=2;v:='second';
insert into t(n,v) values(:n,:v);


--第三次执行
n:=3;v:='third';
insert into t(n,v) values(:n,:v);


v varchar(33)
--第四次执行
n:=4;v:='fourth';
insert into t(n,v) values(:n,:v);


前三次执行只产生了一个游标,也就是说前三次insert共享了一个子游标,而第四次执行则另外产生了一个游标,也就是说并未与前三次产生的游标共享。
产生这种情况的原因就是因为数据库引擎使用了绑定变量分级(graduation)。这个功能的目的是最小化子游标的数量,它是根据绑定变量的长短将绑定变量分为四个级别:
32个字节及其业内被分在第一个级别;33到128个字节被分在第二个级别;129到2000个字节被分在第三个级别,其余大于2000个字节的被分在第四个级别。NUMBER被分在
它的最大产度22个字节级别上。
通过绑定变量分级可以看出,第四次的时候绑定变量长度为33,在第二个级别,这时候数据库引擎认为执行环境发生了变化,则产生新的子游标。


(2)缺点
在WHERE子句中使用绑定变量的缺点是会有一些至关重要的信息对查询优化视而不见,事实上,对于查询优化器来讲,使用字面变量比绑定变量来得更好,使用字面变量可以
提高开销估算的准确性。
例:
在一个1000记录的表中,字段id的值在1和1000之间。
如果查询id小于990的数据,那么查询优化器知道差不多有99%的记录被选中,这时会执行全表扫描。
select * from t where id<990;


如果查询id小于10的记录,那么查询优化器知道差不多有1%的记录被选中,那么会执行索引扫描。
select * from t where id <10;


但是如果使用绑定变量,那么查询优化器就会忽略它们的具体值。为此,oracle9i引入了绑定变量窥测功能(bind variable peeking)。
所谓绑定变量窥测功能就是在物理优化阶段,查询优化器会窥测绑定变量的值,将它作为字面变量来使用,但是这样的问题是它生成的执行计划会依赖第一次产生执行计划所提供
的值。如果第一次执行小于990的查询,那么第二次查询小于10的时候就也会进行全表扫描。
为了解决这个问题,oracle11g引入了扩展的游标共享,也就是数据库引擎为每个子游标的每个选择条件相关的选择性范围,这就部分解决了绑定变量窥测功能的缺陷。


总体来讲,为了提高查询优化器的性能,最好不要使用绑定变量。


总结如下:
SQL语句处理少量数据时--解析时间可能等于或者高于执行时间,使用绑定变量是一种比较好的选择。

SQL语句处理大量数据时--解析时间远远低于执行时间,这是应考虑尽量避免使用绑定变量。


参考资料:Oracle性能诊断艺术 

原创粉丝点击