目录
定义
绑定变量指的是在sql语句中的条件使用变量而不是常量
例如如下条sql
select empno,ename,sal from emp where empno=7788; |
对于oracle来说这三条sql完全不同,在执行的时候都需要硬解析。因为oracle会根据sql的文本来计算在内存里的哈希值(hash),虽然这些sql只有最后几个字符不一样,但是计算出的hash值有天差地别,如果将sql改成如下
select empno,ename,sal from emp where empno=:i; |
用&i来取代后面的值,这样的好处是在执行sql的时候只会对带有变量的sql进行一次硬解析(hard parse)之后只进行软解析(soft prase)。仅三条sql可能不会有什么变化,但是数量级如果是十万或者百万,这样的话节省的消耗可想而之。
硬解析
测试
查看目前数据库解析统计
SQL> select a.*,b.name from v$sesstat a , v$statname b where a.statistic#=b.statistic# and a.sid=(select distinct sid from v$mystat) and b.name like '%parse%'; |
执行sql
SQL> select empno,ename,sal from emp where empno=7788; |
在v$sql中查看执行情况
SQL> select SQL_TEXT,SQL_ID,HASH_VALUE,PARSE_CALLS,EXECUTIONS,LOADS from v$sql where sql_text like 'select empno%'; |
果然,这三条sql被当作不同的语句被分别执行硬解析其中LOADS为硬解析次数
软解析
如果再分别执行一次
SQL> select empno,ename,sal from emp where empno=7788; |
SQL> select SQL_TEXT,SQL_ID,HASH_VALUE,PARSE_CALLS,EXECUTIONS,LOADS from v$sql where sql_text like 'select empno%'; |
再看硬解析统计
SQL> select a.*,b.name from v$sesstat a , v$statname b where a.statistic#=b.statistic# and a.sid=(select distinct sid from v$mystat) and b.name like '%parse%'; |
再次执行parse_calls和executions各自增加1,一次oracle没有再执行硬解析
绑定变量的使用
使用绑定变量可以减少相同或类似语句的重复编译,减少不必要的I/O,提高效率
使用var声明变量
var i number; |
因为变量没有值因此什么都没有查出来
给变量赋值
SQL> exec :i :=7369 |
那解析情况是什么样的呢
SQL_TEXT SQL_ID HASH_VALUE PARSE_CALLS EXECUTIONS LOADS |
执行次数4,解析一次
SQL> select a.*,b.name from v$sesstat a , v$statname b where a.statistic#=b.statistic# and a.sid=(select distinct sid from v$mystat) and b.name like '%parse%'; |
替换变量
&每次都需要重新定义变量
SQL> conn scott/tiger; |
一条sql内如果一个变量需要输入两次的时候可以使用
SQL> select &a,&b from emp where &a=7934; |
这个例子可以看出&a取了不同的列名
&&在同一会话中仅需赋一次变量
SQL> select &&a,&b from emp where &a=7934; |
可以看出即便是后面是&a,由于前面的&&a已经给a赋值,因此第二个&a并没有询问
define
它的作用和&&a差不多,只是不需要询问赋什么值了
SQL> define c=empno |
可以查看define的定义
SQL> define |
如果想取消赋值可以用undefine
SQL> undefine a |
cursor_sharing参数
如果在sql或者前台代码中没有使用绑定变量,可以用该参数在数据库层面上进行处理,但是不推荐
该参数有个值
exact
sql完全一样的时候,不重新编译
similar
sql部分一样时,数据库自动时间变量绑定
fcorce
sql不一样时,强制使用绑定变量
修改该参数(也可使用(alter system修改,但是不推荐)
SQL> alter session set cursor_sharing=similar; |
然后在用替换变量
SQL> select empno,ename,sal from emp where empno=&h; |
查看解析情况
SQL_TEXT SQL_ID HASH_VALUE PARSE_CALLS EXECUTIONS LOADS |
可见oracle自动对变量部分进行了绑定,两次查询仅用一次硬解析