绑定变量及其优缺点

发表于:2012-2-21 10:13

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:robinson_0612    来源:51Testing软件测试网采编

  绑定变量是Oracle解决硬解析的首要利器,能解决OLTP系统中librarycache的过度耗用以提高性能。然刀子磨的太快,使起来锋利,却容易折断。凡事皆有利弊二性,因地制宜,因时制宜,全在如何权衡而已。本文讲述了绑定变量的使用方法,以及绑定变量的优缺点、使用场合。

  一、绑定变量

  提到绑定变量,就不得不了解硬解析与软解析。硬解析简言之即一条SQL语句没有被运行过,处于首次运行,则需要对其进行语法分析,语义识别,跟据统计信息生成最佳的执行计划,然后对其执行。而软解析呢,则是由于在librarycache已经存在与该SQL语句一致的SQL语句文本、运行环境,即有相同的父游标与子游标,采用拿来主义,直接执行即可。软解析同样经历语法分析,语义识别,且生成hashvalue,接下来在librarycache搜索相同的hashvalue,如存在在实施软解析。

  绑定变量

  首先其实质是变量,有些类似于我们经常使用的替代变量,替代变量使用&占位符,只不过绑定变量使用:

  替代变量使用时为&variable_para,相应的绑定变量则为:bind_variable_para

  通常一个SQL语句包含动态部分和静态部分,占位符实质是SQL语句中容易发生变化的部分,通常为其条件或取值范围。动态部分在一般情况下(数据倾斜除外),对执行计划的生成的影响是微乎其微的。故同一SQL语句不同的动态部分产生的执行计划都是相同的。

  二、绑定变量的使用

  1、在SQLPlus中使用绑定变量

  1. SQL> variable eno number;                           -->使用variable定义变量                                              
  2. SQL> exec :eno:=7788;                                                                                                    
  3. SQL> select ename,job,sal from emp where empno=:eno;                                                                     
  4.                                                                                                                          
  5. ENAME      JOB              SAL                                                                                          
  6. ---------- --------- ----------                                                                                          
  7. SCOTT      ANALYST         3000                                                                                          
  8.                                                                                                                          
  9. SQL> col sql_text format a55                                                                                             
  10. SQL> select sql_id,sql_text,executions from v$sqlarea   -->首次查询后在v$sqlarea保存父游标且执行次数EXECUTIONS为1        
  11.   2  where sql_text like '%select ename,job,sal%' and sql_text not like '%from v$sql%';                                  
  12.                                                                                                                          
  13. SQL_ID        SQL_TEXT                                                EXECUTIONS                                         
  14. ------------- ------------------------------------------------------- ----------                                         
  15. dbc6vx6z6n1zv select ename,job,sal from emp where empno=:eno                   1                                         
  16.                                                                                                                          
  17. SQL> select sql_id,hash_value,child_number,sql_text from v$sql -->查询视图v$sql查看该SQL对应的子游标,且CHILD_NUMBER为0  
  18.   2  where sql_text like '%select ename,job,sal%' and sql_text not like '%from v$sql%';                                  
  19.                                                                                                                          
  20. SQL_ID        HASH_VALUE CHILD_NUMBER SQL_TEXT                                                                           
  21. ------------- ---------- ------------ -------------------------------------------------------                            
  22. dbc6vx6z6n1zv 3194619899            0 select ename,job,sal from emp where empno=:eno                                     
  23.                                                                                                                          
  24. SQL> exec :eno:=7369;                                                                                                    
  25. SQL> select ename,job,sal from emp where empno=:eno;  -->再次对变量赋值并查询                                            
  26.                                                                                                                          
  27. ENAME      JOB              SAL                                                                                          
  28. ---------- --------- ----------                                                                                          
  29. SMITH      CLERK            800                                                                                          
  30.                                                                                                                          
  31. SQL> exec :eno:=7521                                                                                                     
  32. SQL> select ename,job,sal from emp where empno=:eno;                                                                     
  33.                                                                                                                          
  34. ENAME      JOB              SAL                                                                                          
  35. ---------- --------- ----------                                                                                          
  36. WARD       SALESMAN        1250                                                                                          
  37.                                                                                                                          
  38. SQL> select sql_id,sql_text,executions from v$sqlarea -->视图v$sqlarea中EXECUTIONS值为3,对应的SQL被执行了3次            
  39.   2  where sql_text like '%select ename,job,sal%' and sql_text not like '%from v$sql%';                                  
  40.                                                                                                                          
  41. SQL_ID        SQL_TEXT                                                EXECUTIONS                                         
  42. ------------- ------------------------------------------------------- ----------                                         
  43. dbc6vx6z6n1zv select ename,job,sal from emp where empno=:eno                   3                                         
  44.                                                                                                                          
  45. -->视图v$sql中对应的子游标也实现了完全共享,保持CHILD_NUMBER为0                                                          
  46. SQL> select sql_id,hash_value,child_number,sql_text from v$sql                                                           
  47.   2  where sql_text like '%select ename,job,sal%' and sql_text not like '%from v$sql%';                                  
  48.                                                                                                                          
  49. SQL_ID        HASH_VALUE CHILD_NUMBER SQL_TEXT                                                                           
  50. ------------- ---------- ------------ -------------------------------------------------------                            
  51. dbc6vx6z6n1zv 3194619899            0 select ename,job,sal from emp where empno=:eno

  2、PL/SQL块中使用绑定变量

  1. SQL> create table t(id number,val number);  -->首先创建表t                                                               
  2.                                                                                                                          
  3. SQL> get get_parse.sql                                                                                                   
  4.   1  select name,value from v$mystat a join v$statname b                                                                 
  5.   2* on a.statistic#=b.statistic# where b.name like 'parse count%';                                                      
  6.                                                                                                                          
  7. SQL> @get_parse.sql   -->获得当前的解析情况,此时hard parase 为63                                                        
  8.                                                                                                                          
  9. NAME                           VALUE                                                                                     
  10. ------------------------- ----------                                                                                     
  11. parse count (total)              394                                                                                     
  12. parse count (hard)                63                                                                                     
  13. parse count (failures)             1                                                                                     
  14.                                                                                                                          
  15. -->下面的pl/sql代码中,Oracle实现自动变量自动绑定,执行了30次的insert操作,但oracle认为每次执行的语句都是一样的          
  16. /**************************************************/                                                                     
  17. /* Author: Robinson Cheng                         */                                                                     
  18. /* Blog:   http://blog.csdn.net/robinson_0612     */                                                                     
  19. /* MSN:    robinson_0612@hotmail.com              */                                                                     
  20. /* QQ:     645746311                              */                                                                     
  21. /**************************************************/                                                                     
  22.                                                                                                                          
  23. SQL> begin                     -->执行pl/sql代码,向表t中插入30条记录                                                    
  24.   2  for i in 1..30 loop                                                                                                 
  25.   3  insert into t values(i,i*2);                                                                                        
  26.   4  end loop;                                                                                                           
  27.   5  commit;                                                                                                             
  28.   6  end;                                                                                                                
  29.   7  /                                                                                                                   
  30.                                                                                                                          
  31. PL/SQL procedure successfully completed.                                                                                 
  32.                                                                                                                          
  33. SQL>  @get_parse              -->代码执行后的结果,硬解析数量仅仅增加了3次                                               
  34.                                                                                                                          
  35. NAME                           VALUE                                                                                     
  36. ------------------------- ----------                                                                                     
  37. parse count (total)              401                                                                                     
  38. parse count (hard)                67                                                                                     
  39. parse count (failures)             1

31/3123>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号