oracle exist 10053,Oracle中利用10053事件来分析Oracle是如何做出最终的执行计划

本文深入介绍了如何利用Oracle的10053事件来查看SQL语句的执行代价信息,从而理解执行计划的生成过程。通过示例展示了SQL查询的转换、统计信息、访问路径成本比较以及最终选择的执行计划。内容涵盖了索引使用、统计分析、代价计算和执行优化等多个方面。
摘要由CSDN通过智能技术生成

我们都知道Oracle从10g开始SQL语句选择什么样的执行方式,是全表扫描,还是走索引的依据是执行代价.那么我们怎么可以去看执行代价的信息呢?通过10053事件可以Oracle依据的执行代价和如何做出执行计划的.如果我们发现某一条SQL语句的执行计划和想像的不一样,我们就可以去看看Oracle所使用的统计分析数据是否准确,是不是统计信息太久没有分析了,重新分析有问题的对象,最终让Oracle做出正确的执行计划。

我们来做一次10053事件的示例:

SQL> create table t1 as select rownum rn from dba_objects;

Table created.

SQL> create index ind_t1 on t1(rn);

Index created.

SQL> exec dbms_stats.gather_table_stats(user,'t1',cascade=>true);

PL/SQL procedure successfully completed.

SQL> create table t2 as select rn, 't2' name from t1 where rn <10000;

Table created.

SQL> create index ind_t2 on t2(rn);

Index created.

SQL> exec dbms_stats.gather_table_stats(user,'t2',cascade=>true);

PL/SQL procedure successfully completed.

SQL> alter session set tracefile_identifier='mysession';

Session altered.

SQL> alter session set events '10053 trace name context forever,level 1';

Session altered.

SQL> explain plan for select t2.* from t1,t2 where t1.rn <100 and t1.rn=t2.rn;

Explained.

SQL> alter session set events '10053 trace name context off';

Session altered.

和上次讲SQL_TRACE的时候一样,生成的trace文件的路径是$ORACLE_BASE/admin/SID/udump目录.

与SQL_TRACE和10046事件不同的是,生成的trace文件不能用tkprof处理,只能阅读原始的trace文件.

对trace文件做一个大体的介绍:

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

Predicate Move-Around (PM)

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

SQL:******* UNPARSED QUERY IS *******

SELECT "T2"."RN" "RN","T2"."NAME" "NAME" FROM "YORKER"."T1" "T1","YORKER"."T2" "T2" WHERE "T1"."RN"<100 AND "T1"."RN"="T2"."RN"

FPD:   Current where clause predicates in SEL$1 (#0) :

"T1"."RN"<100 AND "T1"."RN"="T2"."RN"

kkogcp: try to generate transitive predicate from check constraints for SEL$1 (#0)

predicates with check contraints: "T1"."RN"<100 AND "T1"."RN"="T2"."RN" AND "T2"."RN"<100

after transitive predicate generation: "T1"."RN"<100 AND "T1"."RN"="T2"."RN" AND "T2"."RN"<100

finally: "T1"."RN"<100 AND "T1"."RN"="T2"."RN" AND "T2"."RN"<100

FPD:   Following transitive predicates are generated in SEL$1 (#0) :

"T2"."RN"<100

apadrv-start: call(in-use=340, alloc=0), compile(in-use=31192, alloc=0)

kkoqbc-start

: call(in-use=344, alloc=0), compile(in-use=31976, alloc=0)

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

我们会发现Oracle会对SQL语句做一个转换,把它改成最符合Oracle处理的语句.

比如查询条件变成了 finally: "T1"."RN"<100 AND "T1"."RN"="T2"."RN" AND "T2"."RN"<100

接下来是对一些trace文件中使用的缩写的描述和绑定变量的使用:

The following abbreviations are used by optimizer trace.

CBQT - cost-based query transformation

JPPD - join predicate push-down

FPD - filter push-down

PM - predicate move-around

CVM - complex view merging

SPJ - select-project-join

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

Peeked values of the binds in SQL statement

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

接下来是SQL用到的表,索引的统计信息,如果我们发现这个地方和实际不符,可能需要对对象做分析了.

这些信息包括了表的行数,数据块数,行的平均长度.

列平均长度,非重复的值,空值数,密度,最小值和最大值.

索引的高度,叶子块数目,每一个索引键值占据的块数(LB/K),每一个索引键值对应的表的数据块数目(DB/K).

索引的聚合因子(CLUF).

聚合因子指的是索引中键值在索引块的分布和对应的表中的数据块分布的一种关系.

当索引键值和表中数据排列顺序大致相同时,这个值就越小,当一个索引键值的数据分布在越多的表

的数据块时,这个值越大,意味着使用索引的代价越高.

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

BASE STATISTICAL INFORMATION

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

Table Stats::

Table: T2  Alias: T2

#Rows: 9999  #Blks:  21  AvgRowLen:  6.00

Column (#1): RN(NUMBER)

AvgLen: 4.00 NDV: 9999 Nulls: 0 Density: 1.0001e-004 Min: 1 Max: 9999

Index Stats::

Index: IND_T2  Col#: 1

LVLS: 1  #LB: 21  #DK: 9999  LB/K: 1.00  DB/K: 1.00  CLUF: 17.00

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

Table Stats::

Table: T1  Alias: T1

#Rows: 51060  #Blks:  86  AvgRowLen:  4.00

Column (#1): RN(NUMBER)

AvgLen: 5.00 NDV: 51060 Nulls: 0 Density: 1.9585e-005 Min: 5 Max: 51055

Index Stats::

Index: IND_T1  Col#: 1

LVLS: 1  #LB: 113  #DK: 51060  LB/K: 1.00  DB/K: 1.00  CLUF: 78.00

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

接下来是对各种访问方式的代价的信息,通过比较所有的数据访问方式的代价,选择代价最小的方式

作为执行计划.

对于T1表,列出了

Access Path: TableScan 全表扫描   Cost:  22.86

Access Path: index (index (FFS)) 索引快速扫描  Cost:  27.63

Access Path: index (IndexOnly)只访问索引.(因为只用到了索引数据RN)   Cost: 2.01

可以看到只访问索引的代价最小.

对于T2表有如下访问方式:(最后会走index (RangeScan))

Access Path: TableScan Cost:  6.37

Access Path: index (RangeScan) Cost: 3.01

然后再是对关联顺序的考虑:

T1关联T2

NL Join(nested loops join) Cost: 2051.15

SM Join(Sort merge join) SM cost: 6.02

HA Join (Hash join) HA cost: 5.52

T2关联T1

NL Join(nested loops join) Cost: 475.12

SM Join(Sort merge join) SM cost: 6.02

HA Join (Hash join) HA cost: 5.52

T1关联T2的CPU代价更小,最后会走T1关联T2.

SINGLE TABLE ACCESS PATH

Table: T1  Alias: T1

Card: Original: 51060  Rounded: 95  Computed: 95.02  Non Adjusted: 95.02

Access Path: TableScan

Cost:  22.86  Resp: 22.86  Degree: 0

Cost_io: 21.00  Cost_cpu: 10824444

Resp_io: 21.00  Resp_cpu: 10824444

Access Path: index (index (FFS))

Index: IND_T1

resc_io: 26.00  resc_cpu: 9484923

ix_sel: 0.0000e+000  ix_sel_with_filters: 1

Access Path: index (FFS)

Cost:  27.63  Resp: 27.63  Degree: 1

Cost_io: 26.00  Cost_cpu: 9484923

Resp_io: 26.00  Resp_cpu: 9484923

Access Path: index (IndexOnly)

Index: IND_T1

resc_io: 2.00  resc_cpu: 33443

ix_sel: 0.0018609  ix_sel_with_filters: 0.0018609

Cost: 2.01  Resp: 2.01  Degree: 1

Best:: AccessPath: IndexRange  Index: IND_T1

Cost: 2.01  Degree: 1  Resp: 2.01  Card: 95.02  Bytes: 0

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

SINGLE TABLE ACCESS PATH

Table: T2  Alias: T2

Card: Original: 9999  Rounded: 99  Computed: 99.01  Non Adjusted: 99.01

Access Path: TableScan

Cost:  6.37  Resp: 6.37  Degree: 0

Cost_io: 6.00  Cost_cpu: 2151330

Resp_io: 6.00  Resp_cpu: 2151330

Access Path: index (RangeScan)

Index: IND_T2

resc_io: 3.00  resc_cpu: 58364

ix_sel: 0.009902  ix_sel_with_filters: 0.009902

Cost: 3.01  Resp: 3.01  Degree: 1

Best:: AccessPath: IndexRange  Index: IND_T2

Cost: 3.01  Degree: 1  Resp: 3.01  Card: 99.01  Bytes: 0

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

OPTIMIZER STATISTICS AND COMPUTATIONS

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

GENERAL PLANS

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

Considering cardinality-based initial join order.

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

Join order[1]:  T1[T1]#0  T2[T2]#1

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

Now joining: T2[T2]#1

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

NL Join

Outer table: Card: 95.02  Cost: 2.01  Resp: 2.01  Degree: 1  Bytes: 4

Inner table: T2  Alias: T2

Access Path: TableScan

NL Join:  Cost: 475.12  Resp: 475.12  Degree: 0

Cost_io: 440.00  Cost_cpu: 204409816

Resp_io: 440.00  Resp_cpu: 204409816

kkofmx: index filter:"T2"."RN"<100 AND "T1"."RN"<100

Access Path: index (AllEqJoinGuess)

Index: IND_T2

resc_io: 2.00  resc_cpu: 15463

ix_sel: 1.0001e-004  ix_sel_with_filters: 9.9030e-007

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

Cost_io: 115.60  Cost_cpu: 950127

Resp_io: 115.60  Resp_cpu: 950127

Best NL cost: 115.77

resc: 115.77 resc_io: 115.60 resc_cpu: 950127

resp: 115.77 resp_io: 115.60 resp_cpu: 950127

Join Card:  94.08 = outer (95.02) * inner (99.01) * sel (0.01)

Join Card - Rounded: 94 Computed: 94.08

SM Join

Outer table:

resc: 2.01  card 95.02  bytes: 4  deg: 1  resp: 2.01

Inner table: T2  Alias: T2

resc: 3.01  card: 99.01  bytes: 6  deg: 1  resp: 3.01

using dmeth: 2  #groups: 1

SORT resource      Sort statistics

Sort width:         231 Area size:      202752 Max Area size:    40684544

Degree:               1

Blocks to Sort:       1 Row size:           17 Total Rows:             99

Initial runs:         1 Merge passes:        0 IO Cost / pass:          0

Total IO sort cost: 0      Total CPU sort cost: 5849269

Total Temp space used: 0

SM join: Resc: 6.02  Resp: 6.02  [multiMatchCost=0.00]

SM cost: 6.02

resc: 6.02 resc_io: 5.00 resc_cpu: 5941076

resp: 6.02 resp_io: 5.00 resp_cpu: 5941076

HA Join

Outer table:

resc: 2.01  card 95.02  bytes: 4  deg: 1  resp: 2.01

Inner table: T2  Alias: T2

resc: 3.01  card: 99.01  bytes: 6  deg: 1  resp: 3.01

using dmeth: 2  #groups: 1

Cost per ptn: 0.50  #ptns: 1

hash_area: 0 (max=0)   Hash join: Resc: 5.52  Resp: 5.52  [multiMatchCost=0.00]

HA cost: 5.52

resc: 5.52 resc_io: 5.00 resc_cpu: 3025807

resp: 5.52 resp_io: 5.00 resp_cpu: 3025807

Best:: JoinMethod: Hash

Cost: 5.52  Degree: 1  Resp: 5.52  Card: 94.08  Bytes: 10

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

Best so far: Table#: 0  cost: 2.0057  card: 95.0186  bytes: 380

Table#: 1  cost: 5.5199  card: 94.0778  bytes: 940

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

Join order[2]:  T2[T2]#1  T1[T1]#0

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

Now joining: T1[T1]#0

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

NL Join

Outer table: Card: 99.01  Cost: 3.01  Resp: 3.01  Degree: 1  Bytes: 6

Inner table: T1  Alias: T1

Access Path: TableScan

NL Join:  Cost: 2051.15  Resp: 2051.15  Degree: 0

Cost_io: 1867.00  Cost_cpu: 1071678304

Resp_io: 1867.00  Resp_cpu: 1071678304

Access Path: index (index (FFS))

Index: IND_T1

resc_io: 24.74  resc_cpu: 9484923

ix_sel: 0.0000e+000  ix_sel_with_filters: 1

Inner table: T1  Alias: T1

Access Path: index (FFS)

NL Join:  Cost: 2613.36  Resp: 2613.36  Degree: 0

Cost_io: 2452.00  Cost_cpu: 939065714

Resp_io: 2452.00  Resp_cpu: 939065714

kkofmx: index filter:"T1"."RN"<100

Access Path: index (AllEqJoinGuess)

Index: IND_T1

resc_io: 1.00  resc_cpu: 8171

ix_sel: 1.9585e-005  ix_sel_with_filters: 3.6446e-008

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

Cost_io: 102.00  Cost_cpu: 872287

Resp_io: 102.00  Resp_cpu: 872287

Best NL cost: 102.15

resc: 102.15 resc_io: 102.00 resc_cpu: 872287

resp: 102.15 resp_io: 102.00 resp_cpu: 872287

Join Card:  94.08 = outer (99.01) * inner (95.02) * sel (0.01)

Join Card - Rounded: 94 Computed: 94.08

SM Join

Outer table:

resc: 3.01  card 99.01  bytes: 6  deg: 1  resp: 3.01

Inner table: T1  Alias: T1

resc: 2.01  card: 95.02  bytes: 4  deg: 1  resp: 2.01

using dmeth: 2  #groups: 1

SORT resource      Sort statistics

Sort width:         231 Area size:      202752 Max Area size:    40684544

Degree:               1

Blocks to Sort:       1 Row size:           15 Total Rows:             95

Initial runs:         1 Merge passes:        0 IO Cost / pass:          0

Total IO sort cost: 0      Total CPU sort cost: 5847820

Total Temp space used: 0

SM join: Resc: 6.02  Resp: 6.02  [multiMatchCost=0.00]

SM cost: 6.02

resc: 6.02 resc_io: 5.00 resc_cpu: 5939627

resp: 6.02 resp_io: 5.00 resp_cpu: 5939627

HA Join

Outer table:

resc: 3.01  card 99.01  bytes: 6  deg: 1  resp: 3.01

Inner table: T1  Alias: T1

resc: 2.01  card: 95.02  bytes: 4  deg: 1  resp: 2.01

using dmeth: 2  #groups: 1

Cost per ptn: 0.50  #ptns: 1

hash_area: 0 (max=0)   Hash join: Resc: 5.52  Resp: 5.52  [multiMatchCost=0.00]

HA cost: 5.52

resc: 5.52 resc_io: 5.00 resc_cpu: 3026007

resp: 5.52 resp_io: 5.00 resp_cpu: 3026007

Join order aborted: cost > best plan cost

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

(newjo-stop-1) k:0, spcnt:0, perm:2, maxperm:2000

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

Number of join permutations tried: 2

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

(newjo-save)    [1 0 ]

Final - All Rows Plan:  Best join order: 1

Cost: 5.5199  Degree: 1  Card: 94.0000  Bytes: 940

Resc: 5.5199  Resc_io: 5.0000  Resc_cpu: 3025807

Resp: 5.5199  Resp_io: 5.0000  Resc_cpu: 3025807

kkoipt: Query block SEL$1 (#0)

******* UNPARSED QUERY IS *******

SELECT "T2"."RN" "RN","T2"."NAME" "NAME" FROM "YORKER"."T1" "T1","YORKER"."T2" "T2" WHERE "T1"."RN"<100 AND "T2"."RN"<100 AND "T1"."RN"="T2"."RN"

kkoqbc-end

: call(in-use=31732, alloc=0), compile(in-use=33436, alloc=0)

apadrv-end: call(in-use=31732, alloc=0), compile(in-use=34024, alloc=0)

sql_id=ar0vn3xs804bs.

Current SQL statement for this session:

explain plan for select t2.* from t1,t2 where t1.rn <100 and t1.rn=t2.rn

============

Plan Table

============

------------------------------------------------+-----------------------------------+

| Id  | Operation                     | Name    | Rows  | Bytes | Cost  | Time      |

------------------------------------------------+-----------------------------------+

| 0   | SELECT STATEMENT              |         |       |       |     6 |           |

| 1   |  HASH JOIN                    |         |    94 |   940 |     6 |  00:00:01 |

| 2   |   INDEX RANGE SCAN            | IND_T1  |    95 |   380 |     2 |  00:00:01 |

| 3   |   TABLE ACCESS BY INDEX ROWID | T2      |    99 |   594 |     3 |  00:00:01 |

| 4   |    INDEX RANGE SCAN           | IND_T2  |    99 |       |     2 |  00:00:01 |

------------------------------------------------+-----------------------------------+0b1331709591d260c1c78e86d0c51c18.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值