简单叙述一下所谓的硬解析与软解析:
硬解析可以理解为一个完整的SQL语句解析过程,解析的结果就是生成解析树与执行计划。在硬解析完成之后,该条已经被解析的语句会被加入到一个共享的内存区(专门存储已经解析过的SQL语句),并建立索引(用该条SQL语句以及其他相关的一些信息,用特定的HASH算法进行计算,得到的hash码做为索引的值)。
软解析就是在进行硬解析之前先进行判断,先对语句计算HASH码并到共享SQL内存区进行查找,如果找到相同的SQL,表示同样的SQL已经在此之前已经解析过了,则此时跳过硬解析阶段, 直接从共享区拿到解析树与执行计划继续下面的工作。
很明显的,硬解析要比软解析做更多的工作,这也就意味着硬解析要比软解析要慢(其实要慢很多)。
一些需要注意的细节:在计算HASH码的时候,若两条同样的SQL语句存在大小写不一致的情况(SELECT * FROM A 和 select * from a)则计算出的HASH码不同,意味着不会是软解析,要经过硬解析进行完整解析过程。所以写代码的时候要注意一下。
详细了解请参考这篇文章:《Oracle 硬解析与软解析》http://blog.csdn.net/robinson_0612/article/details/6195483
2、绑定变量
假设要从学生表中查询某个指定学号的学生信息:
学生A, ID 为001 : SELECT * FROM STUDENT WHERE ID=001 //SQL1
学生B, ID 为002 : SELECT * FROM STUDENT WHERE ID=002 //SQL2
分别执行SQL1和SQL2(假设在这之前没有执行过其他的SQL, 就是说SQL1是第一个执行的语句, SQL2是第二个执行的), 根据前面硬解析和软解析中的分析可以知道,SQL1必须要进行硬解析,那SQL2呢?这两句SQL虽然是基本相似的,但是并不完全相同,那么SQL2在执行的时候还是要进行硬解析。要如何做才能让SQL2不用硬解析?这里就要用到绑定变量。
还是以这个例子为例,SQL1和SQL2唯一的区别在于学生的ID是不同的,这就导致了两句SQL算出的HASH码是不同的,要让计算出的HASH码相同,则必须让两个SQL完全一致,可以这样做,我们将具体的学生ID值用一个变量来代替,在SQL语句解析之后将变量在替换成具体的值。
就是变成这样:SELECT * FROM STUDENT WHERE ID=?, 这样SQL语句就变成完全一致的了,就只需要进行一次硬解析,第二次之后无论执行多少次这句SQL都只要进行软解析就可以了。
一句话,绑定变量的实质在于在SQL中的常量(001,002)替换为变量(?),这样就可以做到SQL语句的一致。
3、绑定变量如何应用
3、1 在SQLPLUS中应用绑定变量
SQL> variable sid number;
SQL> exec :sid :=001;
SQL> select * from student where id=:sid;
参考:http://blog.csdn.net/wh62592855/article/details/4778343
3、2 在JAVA中应用绑定变量
String sql = "SELECT * FROM STUDENT WERHE ID=?";
stmt = conn.prepateStatement(sql);
stmt.setString(1, "001"); //将绑定变量替换为常量
stmt.executeQuery();
参考:http://www.doc88.com/p-775898714587.html
3、3 在IBATIS中应用绑定变量
SELECT * FROM STUDENT WEHRE ID=#SID#
注意:使用这种方式ID=$SID$并不会实现SQL的绑定变量,IBATIS在编译的时候也是SQL提交之前就将变量替换掉,就是说如果SID的001, 那么提交的最后提交的 SQL就是SELECT * FROM STUDENT WEHRE ID=001。
另外在看IBATIS相关的资料的时候注意区别IBATIS的动态变量和SQL的绑定变量,比较容易搞混。
参考:http://blog.163.com/sparkle_tiangz/blog/static/1175902032009913114827188/
浙公网安备 33010602011771号