Oracle SQL软硬解析

来源:互联网 发布:什么软件看爱奇艺会员 编辑:程序博客网 时间:2024/06/01 10:46
SGA(共享池)有一块区域 称为库高速缓存,该区域用于存放Oracle以执行过的SQL语句,可以通过v$sql视图来查看该区域所存放的语句。在Oracle中每执行一句语句必然会被解析并存入库高速缓存中,解析包括验证语法、验证提及对象,验证用户权限。如果通过,就会检查库高速缓存确定是否执行过,如果是,Oracle将取回其信息并重用,这种情况被称为软解析。如果不是,Oracle将执行所有工作来生成执行计划,并将其放入缓存以待重用。该方式被称为硬解析。每次硬解析Oracle需要收集所有所需信息,为此Oracle会执行一连串的系统表的查询,这个可以通过打开扩展SQL追踪,查看硬解析的过程。那么Oracle是通过什么来确定SQL是否被执行过?

在相同结果集的情况下

SQL> select * from T_TEST;    ID BM                   MC------- -------------------- ------------------------------      1 001                  记录1      2 002                  记录2SQL> select * from T_TEST where 1=1;    ID BM                   MC------- -------------------- ------------------------------      1 001                  记录1      2 002                  记录2SQL> select * from T_TEST where 2=2;     ID BM                   MC------- -------------------- ------------------------------      1 001                  记录1      2 002                  记录2SQL> select SQL_TEXT from (select * from v$sql order by FIRST_LOAD_TIME desc) where  rownum<4;SQL_TEXT-----------------------------------------------------------select * from T_TEST where 2=2select * from T_TEST where 1=1select * from T_TEST
显然它们被定义为了三个不同的语句,在解析中Oracle会首先把字符串转换为散列值来区分它们的唯一性。换句话说就是只要完全相同的SQL才会触发软解析,那么这个软解析又要什么意义呢?

我们来看看下面这组实验:

SQL> variable v_bm varchar2(100);SQL> exec :v_bm :='001'PL/SQL 过程已成功完成。SQL> select * from T_TEST where BM=:v_bm;     ID BM                   MC------- -------------------- ------------------------------      1 001                  记录1SQL> exec :v_bm :='002'PL/SQL 过程已成功完成。SQL> select * from T_TEST where BM=:v_bm;     ID BM                   MC------- -------------------- ------------------------------      2 002                  记录2SQL> select SQL_TEXT from (select * from v$sql order by FIRST_LOAD_TIME desc) where  rownum<7;SQL_TEXT-----------------------------------------------------------BEGIN :v_bm :='002'; END;select * from T_TEST where BM=:v_bmBEGIN :v_bm :='001'; END;select * from T_TEST where 2=2select * from T_TEST where 1=1select * from T_TEST
由此可以看出select * from T_TEST where BM=:v_bm虽然执行了两次且结果集不同,但在缓存中被当做了一条语句,这种方式在Oracle里被称为绑定变量。
0 0
原创粉丝点击