暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle性能优化:SQL优化思路之四——使用绑定变量

oracleEDU 2017-10-30
1152

在Oracle中,对于一个提交的sql语句,存在两种可选的解析过程,硬解析和软解析。

一个硬解析需要经解析,制定执行路径,优化访问计划等步骤,不仅仅会耗费大量的cpu,更重要的是会占据重要的闩(latch)资源。唯一使得oracle能够重复利用执行计划的方法就是采用绑定变量。绑定变量的实质就是使用变量来代替sql语句中的常量。绑定变量能够使得每次提交的sql语句都完全一样。

构造例子

drop table t purge;

create table t(x int);

select * from v$mystat where rownum=1;

set timing on

未使用绑定变量

begin

    for i in 1 .. 100000

    loop

        execute immediate

        'insert into t values ( '||i||')';

    end loop;

    commit;  

end;

/

耗时:00:00:41.21

使用绑定变量

begin

    for i in 1..100000

    loop

        execute immediate

        'insert into t values(:x)' using i;

    end loop;

    commit;

end;

/

耗时:00:00:06.36

绑定变量的trace例子

准备环境:

SQL> drop table t;

Table dropped.

SQL> create table t(x int);

Table created.

SQL> set linesize 266

SQL> set pagesize 5000

SQL> alter system flush shared_pool;

System altered.

SQL> alter system flush buffer_cache;

System altered.

SQL> alter session set events '10046 trace name context forever,level 12';

Session altered.

未使用绑定变量:

SQL> begin

  2  for i in 1..100000

  3  loop execute immediate

  4  'insert into t values('||i||')';

  5  end loop;

  6  commit;

  7  end;

  8  /

PL/SQL procedure successfully completed.

SQL> alter session set events '10046 trace name context off';

Session altered.

通过如下命令可以查出生成的trc文件:

select d.value

|| '/'

|| LOWER (RTRIM(i.INSTANCE, CHR(0)))

|| '_ora_'

|| p.spid

|| '.trc' trace_file_name

from (select p.spid

      from v$mystat m,v$session s, v$process p

      where  m.statistic#=1 and s.sid=m.sid and p.addr=s.paddr) p,

      (select t.INSTANCE

       FROM v$thread t,v$parameter v

       WHERE v.name='thread'

       AND(v.VALUE=0 OR t.thread#=to_number(v.value))) i,

       (select value

       from v$parameter

       where name='user_dump_dest') d;

TRACE_FILE_NAME

------------------

/u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_5624.trc

tkprof /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_5624.trc home/10046_no_bind.txt sys=no sort=prsela,exeela,fchela

未使用绑定变量的执行结果:

查看10046.txt,发现总共是花费4.38秒,其中解析时间占用了3.32秒

再用10046跟踪使用绑定变量:

drop table t purge;

create table t ( x int );

set linesize 266

set pagesize 5000

alter system flush shared_pool;

alter system flush buffer_cache;

alter session set events '10046 trace name context  forever,level 12';

begin

    for i in 1 .. 10000

    loop

        execute immediate

        'insert into t values ( :x )' using i;   

    end loop;

        commit;

end;

/

alter session set events '10046 trace name context off';

用上面同样的语句查出trace文件。

查看10046.txt,发现总共是花费2.75秒,其中解析时间占用了0.03秒

注意:

1. sqlplus中通过define定义的并不是变量,而只是字符常量,define定义之后,再通过&或&&引用的时候就不需要再输入了,oracle在执行的时候会自动用定义的值进行替换,仅此而已,并不是绑定变量(&&和&一样的功能,不过&&替代过一次之后就不需要再输入了,可以多次替代)

2. 如果define定义的是字符类型,在引用时需要加上单引号;

3. oracle在解析sql时会把plsql中定义的变量转为绑定变量;

4. 存储过程中的参数会自动转化为绑定变量;


最后修改时间:2021-04-28 20:21:14
文章转载自oracleEDU,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论