您的位置:首页 > 数据库

(10)扭转开发习惯,使SQL执行效率更高。

2013-12-06 23:40 363 查看
        我之前检查开发代码时,常会要求他们不要偷懒,要多使用绑定变量(Bind Variable)方式去处理SQL代码。
 所谓绑定变量是Oracle专业术语的说法,开发们或许一时半会不明白绑定变量是什么? 但我下面两段代码
 他们绝对眼熟。
java:
不使用绑定变量,采用串连接:
v_sql="select object_name from objects where object_id="+i;
stmt =conn.prepareStatement(v_sql);
rset=stmt.executeQuery();
stmt.close();

使用绑定变量:  

v_sql = "select object_name from objects where object_id= :x "; //嵌入绑定变量
stmt=conn.prepareStatement(v_sql);
stmt.setString(1,Integer.toString(i)); //为绑定变量赋值
rset = stmt.executeQuery();
stmt.close();

PL/SQL:
 不使用绑定变量,采用串连接:    
'select * from tab where x = '''||传入参数||'''';
   考虑到特殊符号如"'" 符号之类,则需要在传入参数上加上replace进行处理:    
'select * from tab where x = '''||replace(传入参数,'''','''''')||'''';
 使用绑定变量: 
'select * from tab where :x' using 传入参数 ;
 
      明白了吧,它实际上就是SQL语句中的一个占位符,然后再将参数传入替换这个占位符。在开发语言中,不管是Java,还是C#或其它,绝大部份都有提供使用绑定变量方式的写法,只不过可能叫法不同,并且告诉你这种方式通常数据库性能更高,更安全。

绑定变量优点:
1. 使代码运行更安全
       a. 能安全的处理特殊字符,如"'"号,规避了由此可能引发的执行失败
       b. 防止了SQL注入的发生。
2. 确实优化了数据库性能
     在处理一个查询时,数据库先从共享池中查找,看是否已经分析和优化过,如已经分析优化过,Oracle就不需要重复做了,直接执行语句即可,
  只有在找不到时再去硬解析。
          串连接方式依传入参数不同,每次组合出来的SQL每次都不一样,所以每次都要去硬解析
          而绑定变量方式每次的绑定变量是相同的,所以可以复用共享池中的执行计划(即软解析),这样使用绑定变量方式只需第一次硬解析一次,
       后面就不需要了,有效减少了硬解析的次数,使速度会更快,消耗的资源会相对更少。

   硬解析的解释:
     硬解析简言之即一条SQL语句没有被运行过,处于首次运行,则需要对其进行语法分析,语义识别,跟据统计信息生成最佳的执行计划,然后对其执行。

     查看共享池中缓存的SQL语句:  
select sql_text from v$sql where sql_text like '%用户定义的SQL语句%';

绑定变量缺点:
   可能不是最优的执行计划。因为它会复用之前的执行计划,而对于OLAP之类,或查询执行时间间隔很长的SQL语句来说。这么长的时间,数量总量可能发已发生较大变化相比当前,可能有更优        的执行计划供选择。
      
         绑定变量在OLTP类型的系统上是比较适用的,尽量让开发使用它。至于代码平时没太注重这个,但现在又想使用这个特性,Oracle提供了
 "cursor_sharing"参数,可通过修改它,让其强制使用这个特性。 不过生产库如果真要改这参数,最好做好严格的测试。不然有些SQL要是运行时选择了旧的错误的执行计划,还是有风险。所以一定要从源头做起,让开发平常多使用绑定变量。

MAIL:xcl_168@aliyun.com
Blog:http://blog.csdn.net/xcl168


       
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息