暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

dbms_xplan包输出信息

原创 不吃草的牛_Nick 2023-11-04
346

  输出

本节的目标是解释由dbms_xplan包中的某些函数返回的输出中包含的信息。为此,我使用了一个输出样例,该样例由dbms_xplan_output.sql脚本生成,包含大部分可用的部分。因为一页书不足以显示所有的信息,所以不是每个部分的所有信息都显示出来了。我只展示了关键信息。如果缺少了什么,我会指出来。还要注意,对于本节提供的大部分信息,案例和进一步的解释会在本章稍后或第四部分中给出。输出的第一部分如下所示:

 

这部分给出关于SQL语句的以下信息。

Ø  sql_id可以锁定父游标。此信息只有当输出是由display_cursor和display_awr函数生成时才可用。

Ø  child_number与sql_id一起可以锁定子游标。此信息只有当输出是由display_cursor函数生成的时候才可用。

Ø  SQL语句的文本只有当输出是由display_cursor和display_awr函数生成时才可用。

 

第二部分展示的是执行计划的散列值,以及在表格中显示的执行计划本身。

P278

Id

Operation

Name

Rows

Bytes

Cost(%CPU)

Time

 

在这个表格中,为每个操作都提供了估算信息和执行统计。表格的列数直接取决于可用信息的总量。举例来说,关于分区的信息,并行处理的信息或执行统计只有在可以访问时才会显示。出于这个原因,由同一个函数使用一模一样的参数而生成的两份输出也可能会不一样。在本例中,你看到的列是默认可用的。表10-1总结了你可能会看见的所有列。

 

表10-1 包含执行计划的表格的列

描  述

基本信息(总是可用)

 

Id

执行计划中每一步操作(行)的标识符。如果数字以星号开头,就表示此行的谓词信息稍后可供查看

Operation

要执行的操作,也被称作行源操作(row source operation)

Name

执行操作所针对的对象

查询优化器估算

 

Rows and E-Rows

估算的由操作返回的行数

Bytes and E-Bytes

估算的由操作返回的数据总量

TempSpc和E-Temp

估算的操作需要的临时表空间总量(按字节)

Cost(%CPU)

估算的操作成本。以插入方式给出的CPU成本的百分比。注意这个值是在整个执行计划中累积的。换句话说,父操作的成本包含子操作的成本

Time和E-Time

估算的执行操作所需要的时间总和(HH:MM:SS)

分区

 

Pstart

要访问的第一个分区的编号。如果这个编号在解析阶段不可知,则值是KEY或INVALID。当第一个分区会在执行阶段确定的时候使用KEY

Pstop

要访问的最后一个分区的编号。如果这个编号在解析阶段不可知,则值是KEY或INVALID。当最后一个分区会在执行阶段确定的时候使用KEY

并行和分布式处理

 

Inst

对于分布式处理,操作使用的DBLINK的名称

TQ

对于并行处理,表队列用于从属进程之间的通信

IN-OUT

并行或分布式操作之间的关系

PQ Distrib

对于并行处理,生产者用于向消费者发送数据的分布规律

运行时统计*

 

Starts

特定操作被执行的次数。在某些特别的案例中,这个统计显示的是特定内存结构被访问的次数

A-Rows

由操作返回的实际行数

A-Time

执行操作所花费的实际时间总和(HH:MM:SS.FF)

I/O统计*

 

Buffers

在执行期间通过逻辑读访问的块数量

Reads

在执行期间通过物理读访问的块数量

Writes

在执行期间通过物理写访问的块数量

内存使用率统计

 

0Mem

估算的最优化执行需要的内存总量(按字节)

1Mem

估算的一次路径执行需要的内存总量(按字节)

0/1/M

通过optimal/one-pass/multipass模式执行的次数

Used-Mem

操作在最后一次执行期间使用的内存总量(按字节)

Used-Tmp

操作在最后一次执行期间使用的临时空间总量(按千字节)。这个值必须乘以1024才能与其他内存使用量的列保持一致(例如,32K代表32MB)

Max-Tmp

操作使用的临时空间最高总量(按千字节)。这个值必须乘以1024才能与其他内存使用量的列保持一致(例如,32K代表32MB)

 

*只有当执行统计打开时才可用

 

下面的部分展示了查询块名称和对象别名:

Query Block Name / Object Alias(identified by operation id):

------------------------------------------------------------

1 - SEL$1

3 - SEL$1 / T2@SEL$1

4 - SEL$1 / T2@SEL$1

5 - SEL$1 / T1@SEL$1

 

对于执行计划中的每一步操作,可以看到哪一个查询块是与它关联的,或者是在哪个对象上执行的。当SQL语句多次引用同一张表时,这个信息就至关重要了。

 

第四部分展示hint的集合,即概要,这应该足以重现那个特别的执行计划。需要注意的是,概要中并不总是包含所有必要的hint。

Outline Data

-------------

/*+

BEGIN_OUTLINE_DATA

IGNORE_OPTIM_EMBEDDED_HINTS

OPTIMIZER_FEATURES_ENABLE('11,2.0.4')

DB_VERSION('11.2.0.4')

ALL_ROWS

OUTLINE_LEAF(@"SEL$1")

INDEX_RS_ASC(@"SEL$1" "T2"@"SEL$1" ("T2"."ID"))

FULL(@"SEL$1" "T1"@"SEL$1")

LEADING(@"SEL$1" "T2"@"SEL$1" "T1"@"SEL$1")

USE_HASH(@"SEL$1" "T1"@"SEL$1")

END_OUTLINE_DATA

*/

 

下面这部分只有在查询优化器利用绑定变量扫视时才会显示出来。其中提供了每个绑定变量的数据类型和值:

Peeked Binds(identified by position):

-------------------------------------

1 -:T1_ID(NUMBER):6

2 -:T2_ID_MIN(NUMBER):6

3 -:T2_ID_MAX(NUMBER):19

 

下面的部分显示应用了哪个谓词。对于每个操作,都显示了它们是在哪里(行号)以及如何(access、filter或storage)应用的:

Predicate information(identified by operation id):

--------------------------------------------------

1 - filter(:T2_ID_MIN<=:T2_ID_MAX)

2 - access("T1"."N"="T2"."N")

4 - access("T2"."ID">=:T2_ID_MIN AND "T2"."ID"<=:T2_ID_MAX)

5 - filter("T1"."ID">:T1_ID)

 

尽管访问谓词是用于利用高效的访问结构来定位数据行的(例如,内存中的散列表,如操作2;或一个索引,如操作4),而过滤谓词却只有在数据已经从存储它们的结构中抽取出来以后才会应用。此外,当使用了Exadata存储服务器,存储谓词会指定一个特殊的过滤器用于减轻底层存储子系统的负载。注意在这一部分中既会出现SQL语句自身的谓词,也有可能出现由查询优化器或虚拟私有数据库(VPD)策略产生的谓词。在上面的例子中,你看到以下谓词。

Ø  第1行的操作检查绑定变量的值是否会导致空结果集。只有满足:T2_ID_MIN<=:T2_ID_MAX谓词时,查询才能返回数据。如果没有满足这个谓词,就不会执行查询操作的其余动作。

Ø  第2行的散列联接使用"T1"."N"="T2"."N"谓词来联接两个表。换句话说,访问谓词也有可能出现在联接条件上。具体在这个例子中,访问谓词用于指定内存中包含t1表数据的散列表,其散列键为t1.n,是通过由访问t2表返回的列t2.n的值来探测的。

Ø  第4行的索引扫描访问了t_pk索引来查找t1表的id列。在本例中,访问谓词出现在查找执行的键上。

Ø  在第5行,t1表中的所有行都通过一次全表扫描读取出来。然后,将数据行从块中抽取出来时,"T1"."ID">:T1_ID谓词应用于这些行上。

 

下面的部分显示了执行所有操作时会将哪些列作为输出返回。以下是摘录:

Column Projection information(identified by operation id):

----------------------------------------------------------

1 - "T2"."N"[NUMBER,22], "T2"."ID"[NUMBER,22], "T2"."PAD"[VARCHAR2,1000]

2 - (#keys=1)"T2"."N"[NUMBER,22], "T2"."ID"[NUMBER,22], "T2"."PAD"[VARCHAR2,1000]

3 - "T2"."ID"[NUMBER,22], "T2"."N"[NUMBER,22], "T2"."PAD"[VARCHAR2,1000]

4 - "T2".ROWID[ROWID,10], "T2"."ID"[NUMBER,22]

5 - "T1"."N"[NUMBER,22]

 

在本例中,千万要注意,第3行的表访问返回了id、n和pad列,而第5行的表访问只返回了n这一个列。基于这个原因,估算的由第3行操作返回的每一行(7392/14=528字节)数据总量(按字节)要比第5行操作返回的(22776/876=26字节)大得多。

 

最后,有一部分提供了关于优化阶段、环境或SQL语句本身的提醒和警告:

Note

----

 - dynamic_sampling used for this statement (level=2)

 

此处通知你查询优化器使用了动态采样来收集对象统计信息。

 

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论