Monthly Archive for 7月, 2008

ORACLE 10g CBO的问题

第一个问题是bind peeking,很容易造成执行计划不稳定,SQL的执行计划可能会突然会变得很差,造成系统瞬间LOAD很高。
第二个问题是recost for order by,oracle往往会过高的估计排序的成本,从而忽略了索引的选择性,而选择一个避免排序的执行计划,通常这个执行计划都很差。

今天又碰到了这个问题,差点造成故障。由于应用的某个功能,需要对一个时间列gmt_create创建索引,当索引创建后(创建时带着compute statistics参数),一条sql的执行计划就发生了改变:

select * from
(select * from table where member_id=:1 order by member_id,gmt_create desc) where rownum<=100

oracle为了避免排序忽略了member_id上的索引,反而使用gmt_create时间列上的索引,走full index scan来避免排序。

我尝试对索引和列进行分析,都无法使这个sql走到正确的执行计划上,最终只好将这个索引删除。

相比较而言,9i的数据库几乎没有出现过这样的问题,应该是10g在CBO的计算上做了很多改变。

oracle提供了隐含参数,通过设置隐含参数_optim_peek_user_binds=FALSE,可以关掉bind peeking功能。

另外一个隐含参数,_sort_elimination_cost_ratio,描述是:cost ratio for sort eimination under first_rows mode.将这个参数修改为1,降低ORACLE计算order by的成本。这个参数默认是0。看解释有点恐怖:A value of 0 would mean that an execution plan with ORDER BY sort elimination be chosen even if it is more expensive than queries that do a final sorting.不知道ORACLE怎么想的,这个解释表明ORACLE认为排序的成本非常大,只要有机会都会尽量避免排序。

对于我们这种在线系统来说,一旦执行计划走错,系统不会给你太多时间作调整和尝试,负载通常在几秒钟就飙升到100以上,如果不迅速处理,系统很快就会宕掉。可能ORACLE也意识了这个问题,11g提供了Invisible Indexes和SQL Plan Management的特性,这样DBA在尝试做调整时,就算出现问题,我们也可以控制数据库,并有机会作尝试和调整,这对于OLTP系统来说,太重要了。

–EOF–

11g new features

我总结了一些看起来对我们有用的新特性

#PL/SQL
可直接定义序列变量 DECLARE n NUMBER := Seq.Nextval;
增强的正则表达式
PL/SQL CONTINUE statement:循环中,跳过本次循环,继续下次循环

#Availability
standby增强
Compression of Redo Traffic (Only for Gap Resolution) Over the Network in a Data Guard Configuration
压缩传递redo(仅在Gap Resolution的情况下)。

Real-Time Query Capability of Physical Standby Database
这是我觉得非常好的一个功能,就象mysql的复制特性一样,standby可以实时提供读的服务,这样只读的应用就可以部署在standby上了。

Snapshot Standby
可以打开standby进行读写操作,使用完成后,可以继续恢复。这个特性对于我们一些系统非常有用,比如ERP或者测试系统。
Flashback Transaction
可以flashback已经提交的事务(或其相关的事务)。

SMP Scalable Redo Apply
This feature enables faster performance of media recovery and also Data Guard Redo Apply (physical standby database)

DDL With the WAIT Option
在做DDL操作时,如果不能获得DDL_LOCK,可以等待(DDL_LOCK_TIMEOUT初始化参数)后再重试,而不是直接报错。

Enhanced ADD COLUMN Functionality
在已有的表上增加一个not null且含有default value的字段时,不再同时更新所有数据了。

Finer Grained Dependencies
原来的版本中,依赖关系是定义在整个对象上的,而11g进行了优化,依赖关系将更加细化。比如trigger依赖于c1,c2两个字段,如果你新增c3字段,trigger将不会失效。

Invisible Indexes
可以创建一个不可见索引,必须使用hint才可以使用,也是非常有用的小功能,我们在新建或修改索引时,先将其设置为不可见,然后只对某些session生效,以评估其影响。
就象上周六半夜创建一个索引,刚建立成功,一条语句的执行计划就发生错误,由于系统负载已经非常高了,分析也无法完成,只好删除了,有个这个功能就好了。

Materialized View Logging Control
可以对某个session关闭MV log,有些类似我们现在使用的在trigger中的开关。

Minimize Dependent PL/SQL Recompilation After Online Table Redefinition
在线重定义将会尽可能的减少对依赖的对象的影响。

Online Index Creation and Rebuild Enhancements
以前版本中,创建或重建索引都会在开始和结束时短暂持有DML-blocking lock,会堵塞DML操作,11g不需要了。

Read-Only Tables
可以将表设置为只读

RMAN增强
Improved Integration with Data Guard

Fast Incremental Backups on Physical Standby Database
可以在standby上打开block change tracking,RMAN使用change tracking file可以作快速增量备份。

Optimized Undo Backup
备份undo时,不再备份那些恢复时不需要使用的信息。
#Data Warehousing
分区增强:
支持Composite List-Hash,Composite List-List,Composite List-Range,Composite Range-Range类型分区。
Interval Partitioning:Oracle根据需要自动创建分区,尤其适用于小而多的分区情况或者分区不固定的情况。比如每天一个分区,就可以让oracle自动创建。
system partition:分区的规则由应用程序来控制,应用可以选择操作某个分区内的数据。

Virtual Columns 和 Virtual Column-Based Partitioning
可以定义一个虚拟计算出来的列,并且允许根据虚拟列创建分区。比如根据星期几来分区,就完全可以用这个功能实现。

#Cluster
暂时没有看到什么有特点的增强。
#Fault Diagnosability
Automatic Health Monitoring
提供了一个DBMS_HM PL/SQL package用来检查数据库的健康状况,

#Manageability
Enhanced Optimizer Statistics Maintenance
一个OLTP数据库系统,经常会发生当统计信息改变时,sql选择了不正确的执行计划,造成整个系统性能下降或者宕机。
这个功能可以帮助我们,当统计信息变化时,可以将统计信息设置为不可见状态,仅设置对某个session有效,直到测试没问题。

SQL Plan Management
这个功能可以为某个sql创建一个baseline,当sql语句的执行计划发生变化时,

Database Replay
这个功能可以记录数据库的真实负载,然后将其应用在其他的测试系统上。在系统升级,性能测试的时候非常有用。

I/O Calibration
PLSQL function用来测试IO的负载,不知道和orion测试有什么差异。
#Performance
Query Result Cache
查询结果缓存功能,可以将一些频繁的静态数据的查询结果cache起来,提高性能。现在我们通常的做法都是由应用程序做cache实现的,缺点是应用服务器之间的cache不能同步,需要每台服务器单独更新cache.

–EOF–

人生四行

1.自己得行

2.别人说你行

3.说你行的人必须得行

4.身体得行

–EOF–