Chinaunix首页 | 论坛 | 博客
  • 博客访问: 91337200
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类: Oracle

2008-05-24 19:05:59

  来源:

在Oracle9 i 之前的版本里,仅有的两种基于代价的优化器(cost-based optimizer,CBO)模式是ALL_ROWS和FIRST_ROWS优化。传统的FIRST_ROWS SQL优化的一个缺点是,这一算法没有指定数据行检索的。

但是Oracle9 i 引入了多种新的优化器命令:

FIRST_ROWS_1
FIRST_ROWS_10
FIRST_ROWS_100
FIRST_ROWS_1000
FIRST_ROWS_ n 优化会查询优化器,让它选择一个能够把时间减到最小的查询执行计划,以产生查询结果的前 n 行。

你可以在数据库里的多个层次上设置这个新的CBO模式:系统范围内、会话这一层,或者在查询这一层。

alter system set optimizer_mode=first_rows_100;

alter session set optimizer_mode = first_rows_100;

select /*+ first_rows(100) */ from student;

根据Oracle的消息,有了FIRST_ROWS_ n 优化,Oracle查询会为结果集里的前 n 行给出最佳的可能响应时间。带有 n 行结果的快速响应会增强用户对很对应用程序的满意度,因为用户能够更快地获得数据集前面的结果。

ALL_ROWS优化更倾向于完整表格扫描,而FIRST_ROWS优化更倾向于索引的使用,但是Oracle用FIRST_ROWS_ n 优化了这一概念。

在传统的FIRST_ROWS优化里,Oracle CBO更倾向于索引检索,即使它的整体代价要比完整表格扫描更高。这在小表格的情况下尤其如此,因为这样进行完整表格扫描的代价不是太大。

想想下面的例子。

Set autotrace on explain

alter session set optimizer_goal = choose;

select * from emp where sal < 1200;

PLAN -----------------------------------------------------
SELECT STATEMENT (OPTIMIZER=CHOOSE) (COST=62) (ROWS=99)
TABLE ACCESS FULL EMP (COST=62) (ROWS=99)

现在,我们会用FIRST_ROWS优化运行同样的查询。

alter session set optimizer_goal = first_rows;

select * from emp where sal < 1200;

The explain plan is now transformed to:

PLAN -----------------------------------------------------
SELECT STATEMENT (OPTIMIZER=FIRST_ROWS) (COST=102)
  TABLE ACCESS BY INDEX ROWID EMP (COST=102) (ROWS=99)
  INDEX RANGE SCAN SAL_IDX (COST=2) (ROWS=99)

尽管我们预计CBO会倾向于索引,但是我们很意外地看到FIRST_ROWS优化选择了一种比完整表格扫描代价更大的途径。这是就是关键点。在Oracle9 i 之前的版本里,FIRST_ROWS优化是内部规则和代价的混合体,而Oracle9 i 的FIRST_ROWS优化则完全是基于代价的。

在Oracle9 i 之前的版本里,我们会使用OPTIMIZER_INDEX_COST_ADJ参数来控制CBO的倾向,让其选择索引而不是完整表格扫描。

尽管Oracle宣称FIRST_ROWS_ n 优化会让查询更快,但是要记住的是,Oracle9 i CBO所做的一切只考虑了对前几行的访问,而牺牲了查询(的代价)。换句话说,FIRST_ROWS_ n 模式所做的一切是允许优化器作出更加智能的选择:在访问小表格的时候到底是使用索引还是完整表格扫描。由于大多数的Oracle9 i DBA都会在KEEP池里缓冲这些小表格,所以这个参数几乎没有什么用。

本文作者: Donald Burleson做数据库管理员已经有23年了,曾经写过14本关于数据库的书和超过100篇的文章。他是《Oracle内幕(Oracle Internals)》的主编,并经营着Burleson Oracle公司(Burleson Oracle Consulting)。
阅读(440) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~