为了避免硬解析(即为了实现游标缓存),应该使用Bind Variables。这点大家都知道。
然而, Bind Variables如果出现在where子句中,它就会减弱查询优化器的某种能力:根据统计信息和SQL中的字面量选择最优的执行计划。 比如说,假定当前表里的age大都是50岁以下。如果SQL里指定了按 age<50 来查询,那优化器就会来一个全表扫描,快速返回相应数据; 如果SQL里使用的是 age < :age1,那优化器就不敢轻易走全表扫描了 (11g里部分地解决了这个问题,在此不表)。
那倒底要不要用Bind Variables呢? 《Troubleshooting Oracle Performance》给出的方案是:
1. 如果Bind Variable并没有出现where子句,那就没有理由不用它
2. 在小量数据查询环境下,如
OLTP中,硬解析的时间与执行时间相当甚至更大,
应该使用Bind Variable,避免硬解析
3. 在大量数据查询环境下,如
OLAP中,硬解析的时间与执行时间相比只是一个零头,
这时就应用直接用字面量,以免查询优化器选错了执行计划。