first row oracle机制,优化模式区别(all_rows & first_rows_n)

本文探讨了Oracle数据库的FIRST_ROWS优化模式及其变体FIRST_ROWS_N,这两种模式关注于快速返回查询结果。FIRST_ROWS适用于检索单条记录的OLTP系统,而FIRST_ROWS_N允许指定返回行数,成本计算更复杂。在批处理和分组查询中,ALL_ROWS模式更为合适。通过示例展示了不同模式下连接操作的选择和成本计算,揭示了优化器如何根据N值选择执行计划。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

FIRST_ROWS优化模式以最快速度地检索出结果

集中的一行为其指导目标。当系统用户正在使用OLTP系统检索单条记录时,该

优化模式最为有效。但是该模式对于批处理密集型(batch)作业环境来说并不是最理想

的选择,在这种环境中一个查询通常需要检索许多行。FIRST_ROWS提示

一般会强制使用某些索引,而在默认环境(ALL_ROWS)中可能不采用这些索引。在使

用UPDATE和DELETE语句时FIRST_ROWS模式会被忽略,因这些DML操

作中所查询到的所有记录都会被更新或删除。另当使用以下分组语句(如GROUP

BY,DISTINCT,INTERSECT,MINUS和UNION)时FIRST_ROWS模式均被ALL_ROWS模式取代,因为这些语句进行分组

时必须检索所有行。当语句中有ORDER BY子句时,如果索引扫描可以进行实际的排序工作,则优化器将避免额外的排

序。当索引扫描可用并且索引处于内部表(inner table)时,优化器将更倾向于NESTED LOOPS即嵌套循环而非SORT

MERGE排 序连接。

另10g中现有的FIRST_ROWS模式的变体FIRST_ROWS_N来

指定以多少行数最快返回。这个值介于10~1000之间,这个使用FIRST_ROWS_N的新方法是完全基于成本的方法,它对于N的取值较敏感,若N甚

小,优化器就会产生包 括嵌套循环以及索引查找的计划。如果N值较大,优化器也可能生成由散列连接和全表扫描组

成的计划(类似于ALL_ROWS)。 又FIRST_ROW与FIRST_ROWS_N存

在不同,FIRST_ROW模式中保量了部分基于规则的代码,而FIRST_ROWS_N模式则是完完全全基于统计信息计算相应成本,如Oracle文档

所述:

ALL_ROWS优化模式指导查询以最快速度检索出所有行(最佳吞吐量)。当系统用户处于需要大量批处理报告的环境中,该模式较理想。

在实际的SQL硬解析过程中,FIRST_ROWS_N模式将首先以ALL_ROWS模

式的方式计算一次各执行计划的具体代价,之后将我们需要的N条记录代入成本计算中代替实

际全部的候选行(CARD)以得出FIRST_ROWS_N中 的计划成本。

create table test as select *

from dba_objects;

create table testa as select * from

test;

alter session set

events’10053 trace name context forever,level

1′;

–使用10053事件获取成本计算过程trace

alter session set

optimizer_mode=all_rows;

select test.owner from test,testa where

test.object_id=testa.object_id

alter session set events’10053 trace name

context off';

下为ALL_ROWS模式中,最佳连接方式的选 取:

NL Join

Outer table: Card: 9622.00 Cost: 35.37 Resp: 35.37 Degree:

1 Bytes: 7

Inner table: TESTA Alias:

TESTA

Access Path: TableScan

NL Join: Cost:

318924.52 Resp: 318924.52 Degree: 0

Cost_io: 315358.00 Cost_cpu:

27736509932

Resp_io: 315358.00 Resp_cpu:

27736509932

Access Path: index (index

(FFS))

Index: INDA_ID

resc_io: 5.69 resc_cpu:

1304190

ix_sel: 0.0000e+00 ix_sel_with_filters: 1

Inner table: TESTA Alias:

TESTA

Access Path: index (FFS)

NL Join: Cost:

56375.98 Resp: 56375.98 Degree:

0

Cost_io: 54762.00 Cost_cpu:

12551800804

Resp_io: 54762.00 Resp_cpu:

12551800804

Access Path: index

(AllEqJoinGuess)

Index: INDA_ID

resc_io: 1.00 resc_cpu:

8171

ix_sel: 1.0393e-04 ix_sel_with_filters: 1.0393e-04

NL Join: Cost: 9667.48 Resp:

9667.48 Degree: 1

Cost_io: 9657.00 Cost_cpu:

81507910

Resp_io: 9657.00 Resp_cpu:

81507910

Best NL cost: 9667.48

resc: 9667.48 resc_io: 9657.00 resc_cpu:

81507910

resp: 9667.48 resp_io: 9657.00 resp_cpu:

81507910

Join Card: 9622.00 = outer (9622.00) * inner (9622.00) * sel

(1.0393e-04)

Join Card – Rounded: 9622

Computed: 9622.00

SM Join

Outer table:

resc: 35.37 card

9622.00 bytes: 7 deg:

1 resp: 35.37

Inner table: TESTA Alias:

TESTA

resc: 7.17 card:

9622.00 bytes: 3 deg:

1 resp: 7.17

using dmeth: 2 #groups:

1

SORT

resource Sort statistics

Sort

width: 70 Area

size: 131072 Max Area

size: 12582912

Degree: 1

Blocks to

Sort: 17 Row

size: 14 Total

Rows: 9622

Initial

runs: 2 Merge

passes: 1 IO Cost /

pass: 10

Total IO sort cost:

27 Total CPU sort cost: 13931876

Total Temp space used: 254000

SM join: Resc: 203.62 Resp:

203.62 [multiMatchCost=0.00]

HA Join

Outer table:

resc: 35.37 card

9622.00 bytes: 7 deg:

1 resp: 35.37

Inner table: TESTA Alias:

TESTA

resc: 7.17 card:

9622.00 bytes: 3 deg:

1 resp: 7.17

using dmeth: 2 #groups:

1

Cost per ptn: 0.81 #ptns:

1

hash_area: 124

(max=3072) Hash join: Resc:

43.35 Resp: 43.35 [multiMatchCost=0.00]

HA Join (swap)

Outer table:

resc: 7.17 card

9622.00 bytes: 3 deg:

1 resp: 7.17

Inner table: TEST Alias:

TEST

resc: 35.37 card:

9622.00 bytes: 7 deg:

1 resp: 35.37

using dmeth: 2 #groups:

1

Cost per ptn: 0.81 #ptns:

1

hash_area: 124

(max=3072) Hash join: Resc:

43.35 Resp: 43.35 [multiMatchCost=0.00]

HA cost: 43.35

resc: 43.35 resc_io: 42.00 resc_cpu:

10480460

resp: 43.35 resp_io: 42.00 resp_cpu:

10480460

Best:: JoinMethod: Hash

Cost: 43.35 Degree:

1 Resp: 43.35 Card:

9622.00 Bytes: 10

***********************

Best so far: Table#: 0 cost:

35.3706 card: 9622.0000 bytes:

67354

Table#: 1 cost:

43.3476 card: 9622.0000 bytes:

96220

可以看到连接中二表上的候选行都是9622条,实际结果集也是9622条。

我们来看FIRST_ROWS_10情况下的trace:

alter session set events’10053 trace name

context forever,level 1′;

alter session set

optimizer_mode=first_rows_10;

select test.owner from test,testa where

test.object_id=testa.object_id;

alter session set events’10053 trace name

context off';

Now joining: TEST[TEST]#0

***************

NL Join

Outer table: Card: 11.00 Cost:

2.00 Resp: 2.00 Degree:

1 Bytes: 3

Inner table: TEST Alias:

TEST

Access Path: TableScan

NL Join: Cost:

368.08 Resp: 368.08 Degree:

0

Cost_io: 364.00 Cost_cpu:

31713898

Resp_io: 364.00 Resp_cpu:

31713898

Access Path: index

(AllEqJoinGuess)

Index: IND_ID

resc_io: 2.00 resc_cpu:

15503

ix_sel: 1.0393e-04 ix_sel_with_filters: 1.0393e-04

NL Join (ordered): Cost: 24.02 Resp: 24.02 Degree: 1

Cost_io: 24.00 Cost_cpu:

178973

Resp_io: 24.00 Resp_cpu:

178973

Best NL cost: 24.02

resc: 24.02 resc_io: 24.00 resc_cpu:

178973

resp: 24.02 resp_io: 24.00 resp_cpu:

178973

Join Card: 11.00 = outer

(11.00) * inner (9622.00) * sel (1.0393e-04)

Join Card – Rounded: 11 Computed:

11.00

SM Join

Outer table:

resc: 7.17 card

9622.00 bytes: 3 deg:

1 resp: 7.17

Inner table: TEST Alias:

TEST

resc: 35.37 card:

9622.00 bytes: 7 deg:

1 resp: 35.37

using dmeth: 2 #groups:

1

SORT

resource Sort statistics

Sort

width: 70 Area

size: 131072 Max Area

size: 12582912

Degree: 1

Blocks to

Sort: 22 Row

size: 18 Total

Rows: 9622

Initial

runs: 2 Merge

passes: 1 IO Cost /

pass: 14

Total IO sort cost:

36 Total CPU sort cost: 14055006

Total Temp space used: 320000

SORT

resource Sort statistics

Sort

width: 70 Area

size: 131072 Max Area

size: 12582912

Degree: 1

Blocks to

Sort: 17 Row

size: 14 Total

Rows: 9622

Initial

runs: 2 Merge

passes: 1 IO Cost /

pass: 10

Total IO sort cost:

27 Total CPU sort cost: 13931876

Total Temp space used: 254000

SM join: Resc: 109.14 Resp:

109.14 [multiMatchCost=0.00]

SM cost: 109.14

resc: 109.14 resc_io: 105.00 resc_cpu:

32173386

resp: 109.14 resp_io: 105.00 resp_cpu:

32173386

SM Join (with index on outer)

Access Path: index (FullScan)

Index: IND_ID

resc_io: 167.00 resc_cpu:

5134300

ix_sel: 1 ix_sel_with_filters:

1

Cost: 167.66 Resp: 167.66

Degree: 1

Outer table:

resc: 167.66 card

11.00 bytes: 7 deg:

1 resp: 167.66

Inner table: TESTA Alias:

TESTA

resc: 7.17 card:

9622.00 bytes: 3 deg:

1 resp: 7.17

using dmeth: 2 #groups:

1

SORT

resource Sort statistics

Sort

width: 70 Area

size: 131072 Max Area

size: 12582912

Degree: 1

Blocks to

Sort: 17 Row

size: 14 Total

Rows: 9622

Initial

runs: 2 Merge

passes: 1 IO Cost / pass:

10

Total IO sort cost:

27 Total CPU sort cost: 13931876

Total Temp space used: 254000

SM join: Resc: 203.62 Resp:

203.62 [multiMatchCost=0.00]

HA Join

Outer table:

resc: 35.37 card

9622.00 bytes: 7 deg:

1 resp: 35.37

Inner table: TESTA Alias:

TESTA

resc: 7.17 card:

9622.00 bytes: 3 deg:

1 resp: 7.17

using dmeth: 2 #groups:

1

Cost per ptn: 0.81 #ptns:

1

hash_area: 124

(max=3072) Hash join: Resc:

43.35 Resp: 43.35 [multiMatchCost=0.00]

HA Join (swap)

Outer table:

resc: 7.17 card

9622.00 bytes: 3 deg:

1 resp: 7.17

Inner table: TEST Alias:

TEST

resc: 2.00 card:

11.00 bytes: 7 deg:

1 resp: 2.00

using dmeth: 2 #groups:

1

Cost per ptn: 0.69 #ptns:

1

hash_area: 124

(max=3072) Hash join: Resc:

9.85 Resp: 9.85 [multiMatchCost=0.00]

HA cost: 9.85

resc: 9.85 resc_io: 9.00 resc_cpu:

6646477

resp: 9.85 resp_io: 9.00 resp_cpu:

6646477

First K Rows: copy A one plan,

tab=TESTA

Best:: JoinMethod: Hash

Cost: 9.85 Degree:

1 Resp: 9.85 Card:

9622.00 Bytes: 17

***********************

Best so far: Table#: 0 cost:

2.0012 card: 11.0000 bytes:

77

Table#: 1 cost:

9.8546 card: 9622.0000 bytes:

163574

可以看到此次计算中代入了用户希望最先返回的结果 条数11(为10+1),通过设

置连接对象的候选结果集(Card)以到达相关优化目的,相应的COST均有所下降。

下为FIRST_ROWS_1000的情况:

alter session set events’10053 trace name

context forever,level 1′;

alter session set

optimizer_mode=first_rows_1000;

select test.owner from test,testa where

test.object_id=testa.object_id;

alter session set events’10053 trace name

context off';

NL Join

Outer table: Card: 1000.00 Cost: 5.04 Resp: 5.04 Degree:

1 Bytes: 7

Inner table: TESTA Alias:

TESTA

Access Path: TableScan

NL Join: Cost:

33147.66 Resp: 33147.66 Degree:

0

Cost_io: 32777.00 Cost_cpu:

2882616819

Resp_io: 32777.00 Resp_cpu:

2882616819

Access Path: index (index

(FFS))

Index: INDA_ID

resc_io: 5.69 resc_cpu:

1304190

ix_sel: 0.0000e+00 ix_sel_with_filters: 1

Inner table: TESTA Alias:

TESTA

Access Path: index (FFS)

NL Join: Cost:

5861.74 Resp: 5861.74 Degree:

0

Cost_io: 5694.00 Cost_cpu:

1304492819

Resp_io: 5694.00 Resp_cpu:

1304492819

Access Path: index

(AllEqJoinGuess)

Index: INDA_ID

resc_io: 1.00 resc_cpu:

8171

ix_sel: 1.0393e-04 ix_sel_with_filters: 1.0393e-04

NL Join: Cost: 1006.09 Resp:

1006.09 Degree: 1

Cost_io: 1005.00 Cost_cpu:

8474019

Resp_io: 1005.00 Resp_cpu:

8474019

Best NL cost: 1006.09

resc: 1006.09 resc_io: 1005.00 resc_cpu:

8474019

resp: 1006.09 resp_io: 1005.00 resp_cpu:

8474019

Join Card: 1000.00 = outer

(1000.00) * inner (9622.00) * sel (1.0393e-04)

Join Card – Rounded: 1000 Computed:

1000.00

SM Join

Outer table:

resc: 35.37 card

9622.00 bytes: 7 deg:

1 resp: 35.37

Inner table: TESTA Alias:

TESTA

resc: 7.17 card:

9622.00 bytes: 3 deg:

1 resp: 7.17

using dmeth: 2 #groups:

1

SORT

resource Sort statistics

Sort

width: 70 Area

size: 131072 Max Area

size: 12582912

Degree: 1

Blocks to

Sort: 22 Row

size: 18 Total

Rows: 9622

Initial

runs: 2 Merge

passes: 1 IO Cost /

pass: 14

Total IO sort cost:

36 Total CPU sort cost: 14055006

Total Temp space used: 320000

SORT

resource Sort statistics

Sort

width: 70 Area

size: 131072 Max Area

size: 12582912

Degree: 1

Blocks to

Sort: 17 Row

size: 14 Total

Rows: 9622

Initial

runs: 2 Merge

passes: 1 IO Cost /

pass: 10

Total IO sort cost:

27 Total CPU sort cost: 13931876

Total Temp space used: 254000

SM join: Resc: 109.14 Resp:

109.14 [multiMatchCost=0.00]

SM cost: 109.14

resc: 109.14 resc_io: 105.00 resc_cpu:

32173386

resp: 109.14 resp_io: 105.00 resp_cpu:

32173386

SM Join (with index on outer)

Access Path: index (FullScan)

Index: IND_ID

resc_io: 167.00 resc_cpu:

5134300

ix_sel: 1 ix_sel_with_filters:

1

Cost: 167.66 Resp:

167.66 Degree: 1

Outer table:

resc: 167.66 card

1000.00 bytes: 7 deg:

1 resp: 167.66

Inner table: TESTA Alias:

TESTA

resc: 7.17 card:

9622.00 bytes: 3 deg:

1 resp: 7.17

using dmeth: 2 #groups:

1

SORT

resource Sort statistics

Sort

width: 70 Area

size: 131072 Max Area

size: 12582912

Degree: 1

Blocks to

Sort: 17 Row

size: 14

Total

Rows: 9622

Initial

runs: 2 Merge

passes: 1 IO Cost /

pass: 10

Total IO sort cost:

27 Total CPU sort cost: 13931876

Total Temp space used: 254000

SM join: Resc: 203.62 Resp:

203.62 [multiMatchCost=0.00]

HA Join

Outer table:

resc: 35.37 card

9622.00 bytes: 7 deg:

1 resp: 35.37

Inner table: TESTA Alias:

TESTA

resc: 7.17 card:

9622.00 bytes: 3 deg:

1 resp: 7.17

using dmeth: 2 #groups:

1

Cost per ptn: 0.81 #ptns:

1

hash_area: 124

(max=3072) Hash join: Resc:

43.35 Resp: 43.35 [multiMatchCost=0.00]

HA Join (swap)

Outer table:

resc: 7.17 card

9622.00 bytes: 3 deg:

1 resp: 7.17

Inner table: TEST Alias:

TEST

resc: 5.04 card:

1000.00 bytes: 7 deg:

1 resp: 5.04

using dmeth: 2 #groups:

1

Cost per ptn: 0.70 #ptns:

1

hash_area: 124

(max=3072) Hash join: Resc:

12.91 Resp: 12.91 [multiMatchCost=0.00]

HA cost: 12.91

resc: 12.91 resc_io: 12.00 resc_cpu:

7038524

resp: 12.91 resp_io: 12.00 resp_cpu:

7038524

First K Rows: copy A one plan,

tab=TESTA

Best:: JoinMethod: Hash

Cost: 12.91 Degree:

1 Resp: 12.91 Card:

9622.00 Bytes: 17

***********************

Best so far: Table#: 0 cost:

5.0389 card: 1000.0000 bytes:

7000

Table#: 1 cost:

12.9051 card: 9622.0000 bytes:

163574

可以看到此处代入了1000为某一连接对象的候选行数。

MOS上有一个著名的《MIGRATING TO THE COST-BASED

OPTIMIZER》教材,详细介绍了RBO和CBO的区别:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值