1.什么是绑定变量?
通常在高并发的OLTP系统中,可能会出现这样的现象,单个SQL的写法、执行计划、性能都是没问题的,但整个系统的性能就是很差,这表现在当系统并发的数量增加时,整个系统负载很高,CPU占用率接近100%。其实,这种系统性能随着并发量的递增而显著降低的现象,往往是因为这些系统没有使用绑定变量而产生了大量的硬解析所致。因为同一条SQL语句仅仅由于谓词部分变量的不同而在执行的时候就需要重新进行一次硬解析,造成SQL执行计划不能共享,这极大地耗费了系统时间和系统CPU资源。那么怎样才能降低OLTP应用系统的硬解析的数量呢?答案就是使用绑定变量。高并发的OLTP系统若没有使用绑定变量则会导致硬解析很大,这在AWR中的Load Profile部分可以很容易的看出来。
使用绑定变量能够有效降低系统硬解析的数量。对于同一类型的SQL语句若使用了绑定变量,则SQL文本就变得完全相同了,据此计算出来的哈希值也就完全相同,这就具备了可以重用解析树和执行计划的基础条件。这里的同一类型的SQL语句指的是除SQL文本中对应的输入值不同外其它部分都一模一样的SQL语句。例如,银行的查询余额的SQL语句,在成千上万次查询中都只是账户名不同,而SQL语句的其它部分都一样。若没有使用绑定变量,则每查询一次都必须进行一次硬解析。如果使用了绑定变量,假设每次可以节省0.001秒,那么在高并发下上千万次查询节省下来的时间将是非常大的,这在无形中就提高了系统的响应时间。
绑定变量(Bind Variable)其实质是变量,类似于经常使用的替代变量,只不过替代变量使用“&”作为占位符,而绑定变量使用英文冒号(:)作为占位符,替代变量使用方式为&VARIABLE_PARA,相应的绑定变量则为:BIND_VARIABLE_PARA。绑定变量通常出现在SQL文本中,用于替换WHERE或VALUES子句中的具体值。
2.绑定变量使用场景
- 在高并发的OLTP系统中,SQL语句重复执行频度高,但处理的数据量较少,结果集也相对较小,尤其是使用表上的索引来缩小中间结果集,其解析时间通常会接近或高于执行时间,因此,在该场合一定要使用绑定变量,并且最好是使用批量绑定,因为可以有效降低系统硬解析的数量,这也是OLTP类型的系统在数据库端具备良好的性能和可扩展性的前提条件。
- 在OLAP/DSS系统中,SQL语句执行次数相对较少,但返回的数据量较大,其SQL语句执行时间远高于其解析时间,硬解析对系统性能的影响是微乎其微的,因此,使用绑定变量对于总的执行时间影响不大,对系统性能的提升也非常有限
- 对于OLAP和OLTP混合型的应用系统,如果有循环,不管这个循环是在前台代码还是在后台PL/SQL代码中,循环内部的SQL语句一定要使用绑定变量,并且最好是使用批量绑定:至于循环外部的SQL语句,可以不使用绑定变量。
- 总之:绑定变量适合OLTP系统(用户并发高、表中有主键、操作的数据少、执行计划基本相同、sql的重复率高),不适合OLAP(执行计划多变、用户少、sql解析对系统性能影响小)
3.示例:
这里先写一个简单的
select * from t where id=1; select * from t where id=2; select * from t where id=3; ....... 在这些sql语句中,每条sql语句只有一处或两处的值是不同的,我们这里就可以用绑定变量来代替 select * from t where id=:B;
上面分别是三种写法,第一种没有使用绑定变量,第二种使用了绑定变量了,第三种也使用了绑定变量,第一种方法可以看到它没有使用绑定变量,每次执行都会进行一次硬解析(这种是最消耗资源的),第二种看Loads=1表示对象被加载了一次(硬解析),然后parese_calls=4(解析的次数,说明硬解析1次,3次软解析),再看第三种loads和parse_calls都是1,说明只有一次硬解析,这个是消耗资源最少的情况。
4.为什么要绑定变量?
- 减少硬解析的次数
- 减少系统资源开销
- 减少latch争用
5.sql语句处理流程
简单的说,如果该sql语句的执行计划如果存在于share_pool中,那么执行它的时候就不用硬解析(优化器重新给该语句生成新的执行计划,这个过程是相当消耗资源的)了,直接走软解析(不用优化器生成执行计划,用以前生成的就可以)
注意:当sql语句第一次执行时,都会被硬解析的。
这里看一些软解析
当sql硬分析之后,后续的相同的sql都会被软分析
转载于:https://www.modb.pro/db/14349
标签:语句,变量,绑定,sql,SQL,Oracle,解析 From: https://www.cnblogs.com/zmc60/p/17113866.html