一、 什么是绑定变量
绑定变量(bind variable) :
select * from emp where empno=:empno;
是用户放入查询中的占位符,它会告诉Oracle“我会随后为这个变量提供一个值,现在需要生成一个方案,但我实际执行语句的时候,会提供应该使用的实际值”。
实质就是用于替代sql语句中常量的替代变量。绑定变量能够使得每次提交的sql语句都完全一样。

二、 为什么使用绑定变量
使用绑定变量可以减少硬语法分析,优化共享池的使用。在oracle 中,对于一个提交的sql语句,存在两种可选的解析过程, 一种叫做硬解析,一种叫做软解析。
当一个sql语句提交后,oracle会首先检查一下共享缓冲池里有没有与之完全相同的语句,如果有的话只须执行软分析即可,否则就得进行硬分析。
一个硬解析需要经分析、解析、安全检查 、制定执行路径、优化访问计划等等许多的步骤。需消耗大量的cpu及资源。
举个例子,要查询编号为001的儿童,下面两种写法都可以实现:
select * from t_child where childid=’001’;//不使用绑定变量
select * from t_child where childid =: childid;//使用绑定变量
但是实际应用中经常是查询编号为001的儿童一次以后,有可能再也不用;接着你有可能查询儿童’002’,然后查询’003’等等。这样每次查询都是新的查询,都需要硬解析;
而第二个查询语句提供了绑定变量: childid,它的值在查询执行时提供,查询经 过一次编译后,查询方案存储在共享池中,可以用来检索和重用;在性能和伸缩性方面,这两者的差异是巨大的,甚至是惊人的;
若不使用绑定变量,每个查询的条件不同导致共享池中SQL语句数量太多,重用性极低,加速了SQL语句的老化,导致共享池碎片过多。 共享池中不同的SQL语句数量巨大,根据LRU原则,一些语句逐渐老化,最终被清理出共享池;这样就导致shared_pool_size 里面命中率下降,共享池碎片增多,可用内存空间不足。而为了维护共享池内部结构,需要使用latch,一种内部生命周期很短的lock,这将使用大量的cpu 资源,使得性能急剧下降。
不使用绑定变量违背了oracle 的shared pool 的设计的原则,违背了这个设计用来共享的思想。

三、 如何使用绑定变量

public DataSet GetDataTable(T_child entity)
{
ArrayList parmlist = new ArrayList();
ArrayList valuelist = new ArrayList();
String sql = "select * from t_child where childid =: childid";
parmlist.Add("childid");
valuelist.Add(entity.Childid);
DataSet ds = SqlHelper(sql, dbName, valuelist, parmlist, ref errorMsg);
return ds;
}

调用以下方法:

public static DataSet SqlHelper(string query, string dataBaseName, ArrayList bllist, ArrayList pamlist, ref string returnMessage)
{
AdoHelper adoHelper = null;
try
{
adoHelper = DatabaseConnectEntity.CreateHelper(dataBaseName);
IDataParameter[] parameters = new IDataParameter[bllist.Count];
if (adoHelper._dbFactory.DatabaseType == DatabaseType.DB_Oracle)
{
ArrayList paramlist = new ArrayList();
for (int i = ; i < bllist.Count; i++)
{
OracleParameter parm;
string paramvalue = "";
if (bllist[i] == null)
{
parm = new OracleParameter(pamlist[i].ToString(), null);
}
else
{
paramvalue = bllist[i].ToString();
if (bllist[i].GetType().ToString() == "System.DateTime")
{
parm = new OracleParameter(pamlist[i].ToString(), OracleType.DateTime);
parm.Value = paramvalue.Trim();
}
else
{
parm = new OracleParameter(pamlist[i].ToString(), paramvalue.Trim());
}
}
paramlist.Add(parm);
}
paramlist.CopyTo(parameters, );
}
else
{
returnMessage = "非ORACLE数据库不能执行此存储过程!";
return null;
}
DataSet ds = adoHelper.ExecuteDataSet(CommandType.Text, query, parameters);
return ds;
}
catch (Exception ex)
{
returnMessage = "查询失败!" + ex.ToString();
return null;
}
finally
{
adoHelper.Close();
}
}

四、 绑定变量使用限制条件
在对建有索引的字段(包括字段集),且字段(集)的集的势非常大时,使用绑定变量可能会导致无法选择最优的查询计划,因而会使查询效率非常低。
集的势非常大【即倾斜性很严重 】,如:一个索引字段,总记录数有1000条,有A值的有900条;B值50条;C值50条,那么我们就说这个字段的集的势很大。当然这个集的势的算法比较复杂,他跟查询条件、是否建索引等都有关系。比如:若全表扫描:集的势=记录数;索引扫描,查询条件“=”:集的势=记录数/字段上的唯一值数 ;
那么为什么说集的势大时使用绑定变量反而会时查询效率变低呢?
因为Oracle在执行SQL语句时,会计算各个访问路径的代价,采用最小代价的访问路径作为语句的执行计划。若第一次查询的条件刚好是索引字段中记录最多的值,那么这个索引扫描成本就非常高,根据分析会使用全表扫描,并将这个查询计划保存到共享池中,而当查询其他值时成本很低,但由于采用绑定变量,不再进行硬解析,也就是不去分析采用什么执行计划,而是直接使用之前的这个查询计划,这样会导致无法选择最优的查询计划。
对于隔相当一段时间才执行一次的sql语句,利用绑定变量的好处会被不能有效利用优化器而抵消。

Oracle绑定变量在C#.NET中的应用及意义的更多相关文章

  1. [转]ORACLE 绑定变量用法总结

    转:http://blog.csdn.net/wanghai__/article/details/4778343 在oracle 中,对于一个提交的sql语句,存在两种可选的解析过程, 一种叫做硬解析 ...

  2. ORACLE 绑定变量用法总结 .

    之前对ORACLE中的变量一直没个太清楚的认识,比如说使用:.&.&&.DEIFINE.VARIABLE……等等.今天正好闲下来,上网搜了搜相关的文章,汇总了一下,贴在这里,方 ...

  3. SQL优化 | Oracle 绑定变量

    之前整理过一篇有关绑定变量的文章,不太详细,重新补充一下. Oracle 绑定变量 http://www.cndba.cn/Dave/article/1275 一.绑定变量 bind variable ...

  4. Oracle绑定变量

    select * from table where id = ? 类似于上面这样的sql,如果不用绑定变量,每次执行时Oracle会认为是不同的sql,会在每次执行时生成一遍执行计划,而执行计划的生成 ...

  5. oracle 绑定变量

    “绑定变量”这个词也许对于某些人来说看以来陌生,其实我们在很早的时候就已经开始运用它了. 在java中使用的PrepareStatement对象,大家一定会说这不是将sql语句做预编译操作嘛,被封装的 ...

  6. Oracle绑定变量优缺点

    参考:http://f.dataguru.cn/thread-208881-1-1.html 参考:http://blog.sina.com.cn/s/blog_4d9ece9a0100caw8.ht ...

  7. Oracle 绑定变量窥视

    绑定变量窥视功能是数据库的一个特性,自ORACLE9i版本开始引入,默认是开启的. “绑定变量窥视”表示,查询优化器在第一次调用游标时,会观察用户定义的绑定变量的值,允许优化器来确认过滤条件的选择性, ...

  8. oracle绑定变量测试及性能对比

    1.创建测试数据 2.查看cursor_sharing的值 SQL> show parameter cursor_sharing; NAME TYPE VALUE --------------- ...

  9. ORACLE绑定变量隐式转换导致性能问题

    年后一次系统升级后,监控数据库的工具DPA发现数据库的Total Wait时间突然飙增,如下截图所示,数据库的总体等待时间对比升级前飙增了非常多 另外就是发现出现了较多的等待事件,主要有latch: ...

随机推荐

  1. vscode 集成 cygwin 的注意事项

    vscode 集成 cygwin vscode 现在是我的主力开发编辑器,它自带 terminal 不需要我各种切换,我还想要在 windows 下执行一些简单的 .sh 文件.所以,我希望有一款工具 ...

  2. LeetCode: 107_Binary Tree Level Order Traversal II | 二叉树自底向上的层次遍历 | Easy

    本题和上题一样同属于层次遍历,不同的是本题从底层往上遍历,如下: 代码如下: struct TreeNode { int val; TreeNode* left; TreeNode* right; T ...

  3. springboot创建统一异常拦截器全局处理 异常

    1.创建Exception类 public class MyException extends RuntimeException { private ErrorCodeEnum errorCode; ...

  4. 用synchronized同时修饰父类和子类,线程是安全的。即对象锁可重入

    public class SyncDubbo { static class Main { public int i = 10; public synchronized void operationSu ...

  5. Neo4j使用Cypher查询图形数据

    Neo4j使用Cypher查询图形数据,Cypher是描述性的图形查询语言,语法简单,功能强大,由于Neo4j在图形数据库家族中处于绝对领先的地位,拥有众多的用户基数,使得Cypher成为图形查询语言 ...

  6. Java高并发之线程池详解

    线程池优势 在业务场景中, 如果一个对象创建销毁开销比较大, 那么此时建议池化对象进行管理. 例如线程, jdbc连接等等, 在高并发场景中, 如果可以复用之前销毁的对象, 那么系统效率将大大提升. ...

  7. 三、TortoiseGit之配置密钥

    TortoiseGit使用扩展名为ppk的密钥,而不是ssh-keygen生成的rsa密钥. 也就是说使用 ssh-keygen  -t rsa  -C "username@email.co ...

  8. JavaWeb学习 (十二)————使用Session防止表单重复提交

    在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交. 一.表单重复提 ...

  9. mybatis教程4(动态SQL)

    动态SQL语句 MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句的痛苦.例如拼接时要确保不能忘记添加必要的空 ...

  10. Spring之Bean的配置方式

    在博客中为了演示容器Bean实例化时暴露出的几个接口,将UserBean配置在XML中,其实常见的Bean的配置有3种.1.基于xml配置Bean 2.使用注解定义Bean 3.基于java类提供Be ...