Month: December 2010

倒底要不要使用Bind Variables

为了避免硬解析(即为了实现游标缓存),应该使用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中,硬解析的时间与执行时间相比只是一个零头, 这时就应用直接用字面量,以免查询优化器选错了执行计划。

软解析、硬解析及其对性能的影响

SQL解析时要经历以下几个步骤:    1. VPD相关处理    2. 语法、语义、权限检查    3. 对SQL进行逻辑优化    4. 再进行物理优化 这其中会牵涉到游标的缓存读写: 看下缓存里有没有所需的游标,有就读出来直接用,没有就要创建一个出来用,用完后塞到缓存中。 如果缓存已存在,那就只需执行上面的步骤#1和步骤#2。 这就是软解析。 否则,就会执行所有步骤。这就是硬解析。 由于步骤#3和#4比较耗费CPU,而在缓存里创建新游标又比较耗内存,因此硬解析比软解析的开销要大很多,因此应该尽量避免硬解析。 要避免硬解析,就得尽量重用缓存中的游标。而游标是以SQL为Key的,要重用游标,就要尽量对同样的操作使用同样的SQL(大小写、空格都要一样),也就是说要用Bind Variables. ============================================================ 不过,软硬解析代价都其实都很高,因为它们都会产生对共享资源的竞争使用。 Oracle中,这些操作的并发性达到了“可串行化”级别,对性能的影响很大。

Notes on ‘Refactoring ‘ — 6.1 Replace Inheritance with Delegation

When?   You find that some of the superclass operations aren’t really true of the subclass. The code is saying the subclass has some interface that it doesn’t have. This is confusing. How to solve it?   1. The subclass doesn’t extend its superclass anymore   2. Instead, subclass should REFERENCE superclass to use it …

Notes on ‘Refactoring ‘ — 6.1 Replace Inheritance with Delegation Read More »

Notes on ‘Refactoring ‘ — 5.2 Replace Exception with Test

Before Refactoring try{ return list.get(index); }catch(IndexOutOfBoundsExceptione){ return null; } After Refactoring if(index >= list.size()){ return null; } return list.get(index); Benefits: Avoid too many exceptions since it is not so good to read and it should only be used for an exception flow.

Notes on ‘Refactoring ‘ — 5.1 Seperate Query from Modifier

Before Refactoring getPersonAndIncreaseCounter(){ counter ++; return person; } After Refactoring getPerson(){ return person; } increaseCounter{ counter ++; } Benefits     You can call getPerson() as often as you like. You have a lot less to worry about. Exception    It’s OK to change personCache in getPerson() method.