oracle 执行计划详解

news2024/12/22 18:51:46

执行计划是指示 Oracle 如何获取和过滤数据、产生最终的结果集,是影响SQL 语句执行性能的关键因素。在深入了解执行计划之前,首先需要知道执行计划是在什么时候产生的,以及如何让 SQL 引擎为语句生成执行划。

先了解 SQL 语句的处理执行过程。当一条语句提交到 Oracle 后,SQL 引擎会分为三个步骤对其处理和执行:解析(Parse)、执行(Execute)和获取(Fetch),分别由 SQL 引擎的不同组件完成。

在这里插入图片描述

Oracle SQL 引擎的体系结构

一、SQL 编译器(SQL Compiler)

SQL 编译器由解析器(Parser)、查询优化器(Query Optimizer)和行源生成器(Row Source Generator)组成。

 解析器(Parser):执行对 SQL 语句的语法、语义分析,将查询中的视图展开、划分为小的查询块。
 查询优化器(Query Optimizer):Oracle 数据库中 SQL 优化器(SQLOptimizer)是 SQL 分析和执行的优化工具,为语句生成一组可能被使用的执行计划,估算出每个执行计划的代价,并调用计划生成器(Plan Generator)生成计划,比较计划的代价,最终选择一个代价最小的计划,优化器负责生成 SQL 的执行计划。它对优化器来说输入的是解析后的 SQL 语句,输出的是执行计划。
查询优化器由查询转换器(Query Transform)、代价估算器(Estimator)和计划生成器(Plan Generator)组成。
在这里插入图片描述

Oracle 两种优化器
 RBO(Rule-Based Optimizer):基于规则的优化器
 CBO(Cost-Based Optimizer):基于成本的优化器(11g 默认优化器)

从 Oracle 10g 开始,RBO 已经被弃用,但是我们依然可以通过 Hint 方式来使用它。
上述优化器实际上指的是基于代价的优化器(Cost Based Optimizer,CBO),CBO 也是当前采用的所有优化和调优技术的核心基础。

查询转换器(Query Transformer):决定是否重写用户的查询(包括视图合并、子查询反嵌套),以生成更好的查询计划。

代 价 估 算 器 ( Estimator ) : 使 用 统 计 数 据 来 估 算 操 作 的 选 择 率(Selectivity)、返回数据集(Cardinality)和代价,并最终估算出整个执行计划的代价。

计划生成器(Plan Generator):计划生成器会考虑可能的访问路径(AccessPath)、关联方法和关联顺序,生成不同的执行计划,让查询优化器从这些计划中选择出代价最小的一个计划。

行源生成器(Row Source Generator):从优化器接收到优化的执行计划后,为该计划生成行源(Row Source)。行源是一个可被迭代控制的结构体,它能以迭代方式处理一组数据行、并生成一组数据行。

SQL 执行引擎(SQL Execution Engine):SQL 执行引擎依照语句的执行计划进行操作,产生查询结果。在每一个操作中,SQL 执行引擎会以迭代方式执行行源、生成数据行。

Oracle 引入一些新的优化技术时,例如,SPM、SPA 等,这些组件会与 SQL引擎的组件融合,提供更好的优化和调优方法。

CBO 优化模式
(1)FIRST_ROWS(n)
(2)ALL_ROWS (默认值)

查看参数:

SQL> show parameter optimizer_mode

在同一系统环境下,同一条 SQL 语句选用不同的优化模式,将可能令优化器生成不同的执行计划。

修改 CBO 优化 模式:
(1)Sessions 级别:

SQL> alter session set optimizer_mode = all_rows;

(2)系统级别:修改 spfile 参数

SQL> alter system set OPTIMIZER_MODE = ALL_ROWS;

(3)语句级别:用 Hint(/*+ … */)来设定

SQL> Select /*+ first_rows(10) */ name from table;

二、SQL 语句的执行过程

用户发出待执行的 SQL 语句 -> 解析 -> 优化器(查询转换,RBO 或 CBO处理)-> 生成执行计划 -> 实际执行 -> 返回结果。
在这里插入图片描述
处理步骤包括:
1、语法检查(syntax check): 检查此 sql 的拼写是否语法。例如:

SELECT * FORM employees;

2、语义检查(semantic check): 访问对象是否存在及该用户是否具备相应的权限。例如:

SELECT * FROM nonexistent_table;

3、共享池检查(Shared Pool Check),生成 SQL 语句的 Hash 值和 SQL_ID,按 SQL_ID 及其 Hash 值 Shared Pool 中查找匹配的相同 SQL 语句。

4、加载 SQL 代码至内存,生成内存共享数据(cursor),生成执行计划(execution plan)。

5、执行 SQL,返回结果(execute and return)。

SQL 解析类型:
Hard Parse (硬解析): 也称为"library cache miss"。进行语法检查、语义检查,加载 SQL 语句至 Shared pool 的 Library Cache 中,生成执行计划。

大小写、空格等差异都会令同一条语句被解析为不同的语句。由于须要加载到内存中,需要专门分配内存空间并进行内存管理,因此,硬解析需要占用 CPU、获取 library cache latch 和 shared pool latch 等资源,对于 SQL 的执行来说,硬解析是最消耗资源的。所以,应当尽量避免解析,力求实现 SQL 语句的一次解析,多次执行。

Soft Parse (软解析): 也称为"library cache hit"。在 SQL 语法和语义检查后,如果在 Shared Pool 中找到了与之完全相同的 SQL 语句,则无需执行内存加载,直接调用已有的执行计划并执行。

提高软解析的方法包括:增加 shared_pool_size,使用绑定变量优化 SQL语句,调整 cursor_sharing 参数等。

Softer Soft Parse(软软解析): 当设置了 session_cached_cursors 这个参数之后,Cursor 被直接 Cache 在当前 Session 的 UGA(User Global Area)中的,会话端重复执行相同的 SQL 时,先在 UGA 中查找,如果发现完全相同的Cursor,就直接到 Shared pool 中取结果,也就实现了 Softer Soft Parse。

SQL>alter system flush shared_pool;
SQL>create table test as select * from dba_objects where 1<>1;
--收集 test 表统计信息
SQL>exec dbms_stats.gather_table_stats('sys','test');

下面语句为硬解析:

SQL>select * from test where object_id=20;
SQL>select * from test where object_id=30;
SQL>select * from test where object_id=40;
SQL>select * from test where object_id=50;

下面语句为软件解析:

var oid number
exec :oid:=20;
select * from test where object_id=:oid;
exec :oid:=30;
select * from test where object_id=:oid;
exec :oid:=40;
select * from test where object_id=:oid;
exec :oid:=50;
select * from test where object_id=:oid;

下面语句为软软解析:

declare
i number;
begin
for i in 1..14 loop
execute immediate 'select * from test where object_id=:i' using i;
end loop;
end;
/

查询语句执行情况:

col sql_text format a40
select sql_text,parse_calls,loads,executions from v$sql s where sql_text like 'select * from test where object_id%' order by 1,2,3,4;
SQL_TEXT                              PARSE_CALLS   LOADS   EXECUTIONS
------------------------------------- ----------- ---------- ----------
select * from test where object_id=20 1            1              1
select * from test where object_id=30 1            1              1
select * from test where object_id=40 1            1              1
select * from test where object_id=50 1            1              1
select * from test where object_id=:i 1            1              14
select * from test where object_id=:oid 4         1             4

设置 cursor_sharing 参数为 force,设置为 force 后,oracle 将 2 条类似的SQL 的谓词用一个变量代替,同时将它们看做同一条 SQL 语句处理。这种方式很粗暴,但极可能造成执行计划的不准确。适用场景:在无法将应用的代码修改为绑定变量情况下,oracle 提供的一种解决方法。

alter system flush shared_pool;
alter session set cursor_sharing=force;

查询语句:

select * from test where object_id=60;
select * from test where object_id=70;
select * from test where object_id=80;
select * from test where object_id=90;
select * from test where object_id=100;
select * from test where object_id=110;

查询语句执行情况:

col sql_text format a50
select sql_id,child_number,sql_text,buffer_gets
from v$sql where sql_text like 'select * from test where object_id%';

三、生成和显示执行计划

任何一条 SQL 语句要正确运行并返回结果,SQL 执行引擎都必须获得一个相应的执行计划。当缓存当中找不到与当前环境相匹配的执行计划时,SQL 编译器会解析和生成一个相应的执行计划。已经生成的执行计划会驻留在缓存当中,直至其失效或者被清出缓存。

执行计划 (Execution Plan)

 执行计划显示一条 SQL 语句的详细执行步骤,包括从数据库读取数据以及对数据的处理。
 这些步骤表示为一组数据库运算操作(Operation),使用这些运算操作并返回数据行。
 这些运算操作及其实施的顺序由优化器使用查询转换及物理优化技术的组合来确定。
 执行计划通常以表格的形式显示,但它实际上为树形。
在这里插入图片描述
同样的 SQL 语句,其执行计划会因用户环境(Schemas)和执行成本(Costs)的不同而改变,例如:
 在不同的数据库中执行;
 以不同的用户执行;
 用户数据方案变化(例如修改了索引);
 不同的数据量和统计信息;
 语句的变量参数输入了不同的类型和取值;
 系统初始参数的变化(包括改变了全局或局部会话的参数等,如:优化模式改变等)。

通过包 dbms_xplan 显示计划

dbms_xplan 包可以根据我们选择的函数以及输入的参数来格式化显示相关的执行计划。dbms_xplan 使用函数用于输出格式化的执行计划,display、display_cursor、display_sqlset,分别用于显示 explain plan 命令解释的计划、内存中的执行计划、sql 优化集中语句的计划。

display函数
display 函数用于显示存储在 plan_table 中的执行计划,此外,如果从视图v$sql_plan_statistics_all 可以获得该执行计划的相关统计数据,display 也可以格式化输出这些数据。

参数描述:
table_name:存储查询计划的表名(不区分大小写),默认值为 plan_table。

statement_id:sql 语句 id。在 plan_table 中,每条语句的执行计划都会有一个唯一的 id 来标识。这个 id 可以在执行 explain plan 命令时,通过 set statement_id 子句来指定。如果输入为 null,则会获取最近一条被解释的语句。

format:输出格式。在 display 函数中,有以下预定义的格式(模板)可供选择:

  • ‘basic’:基本格式。输出的内容最少,仅仅输出查询计划中每个操作的 id、名称和选项以及操作的对象名。
  • ‘typical’:典型格式。输出的内容是我们进行语句调优时大多数情况下所需要的信息。除了基本格式中的内容外,还会输出优化器估算出的每个操作的记录行数、字节数、代价和时间,以及相关的提示信息(如远程 sql、优化器建议等)。如果存在谓词(predicate)条件,还会输出每个操作中的过滤(filter)条件和访问(access)条件。此外,如果查询涉及分区表,还会输出分区裁剪信息;如果查询涉及并行查询,还会输出并行操作的相关信息(如表队列信息、并行查询分布方式等)。这种格式是默认格式。
  • ‘serial’:串行执行格式。这种格式和典型格式的输出内容基本一致,不同
    之处在于,对并行查询,它不会输出相关的并行内容。
  • ‘all’:完全格式。输出的内容相对完整。除了典型格式的内容以外,还会输出字段投射信息和别名信息。

除了这些预定义的格式外,用户还可以通过在格式化字符串中添加或者屏蔽一些关键词进行细化输出。每一个细化选项代表了输出内容中的单个信息(可能是执行计划表中的一个列,也可能是一个附加信息)。在 display 函数中,有以下细化控制选项可供选择:

  • rows:优化器估算出的记录行数;
  • bytes:优化器估算出的字节数;
  • cost:优化器估算出的代价;
  • partition:分区裁剪;
  • parallel:并行查询;
  • predicate:谓词;
  • projection:字段投射;
  • alias:别名;
  • remote:分布式查询信息;
  • note:相关注释信息。

细化控制选项和预定格式一起使用。例如,如果希望输出基本格式内容,并输出优化器估算出的记录行数,可以用“basic rows”作为格式字符串;而如果希望输出典型格式,但不要其中的谓词条件,则可以输入“typical -predicate”作为格式字符串,即在希望被屏蔽信息的对应控制选项前加上“-”。

filter_preds:该参数接收合法的谓词过滤条件(可以是谓词逻辑表达式,也可以包含子查询),以过滤从查询计划表中读取的内容。例如,可以输入“cost >10”以限制输出所有估算代价大于 10 的操作。

--生成执行计划
explain plan for select * from scott.dept;

--典型格式输出执行计划,即默认 typical 格式输出
select * from table(dbms_xplan.display());
---------------------------------------------
|Id| Operation        | Name | Rows | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------
|0 | SELECT STATEMENT |      | 4    | 80    | 3 (0)      | 00:00:01 |
|1 | TABLE ACCESS FULL| DEPT | 4    | 80    | 3 (0)      | 00:00:01 |
--------------------------------------------------------------------

--基本格式输出执行计划,包括 ROWS BYTES
select * from table(dbms_xplan.display(null,null,'BASIC ROWS BYTES'));
-----------------------------------------------
| Id | Operation        | Name | Rows | Bytes |
-----------------------------------------------
| 0  | SELECT STATEMENT |      | 4    | 80    |
| 1  | TABLE ACCESS FULL| DEPT | 4    | 80    |
-----------------------------------------------

--基本格式输出执行计划,包括 ROWS BYTES COST
select * from table(dbms_xplan.display(null,null,'BASIC ROWS BYTES COST'));
---------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
---------------------------------------------------------------
| 0 | SELECT STATEMENT | | 4 | 80 | 3 (0)|
| 1 | TABLE ACCESS FULL| DEPT | 4 | 80 | 3 (0)|
---------------------------------------------------------------

--典型格式输出执行计划
select * from table(dbms_xplan.display(null,null,'TYPICAL'));
-----------------------------------------------------------------
|Id|Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------
|0| SELECT STATEMENT | | 4 | 80 | 3 (0)| 00:00:01 |
|1| TABLE ACCESS FULL| DEPT | 4 | 80 | 3 (0)| 00:00:01 |
-----------------------------------------------------------------

--屏蔽 rows
select * from table(dbms_xplan.display(null,null,'TYPICAL -rows'));
-----------------------------------------------------------------
| Id | Operation | Name | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------
| 0 | SELECT STATEMENT | | 80 | 3 (0)| 00:00:01 |
| 1 | TABLE ACCESS FULL| DEPT | 80 | 3 (0)| 00:00:01 |
-----------------------------------------------------------------

display_cursor函数
display_cursor 函数可以显示内存中一个或者多个游标的执行计划。同样,可以通过输入参数限定 sql、游标以及输出格式。用户必须对视图 v$sql、v$sql_plan 和 v$sql_plan_statistics_all 的 select 有权限,才能正常调用display_cursor 函数。

参数描述:
sql_id:所显示执行计划的 sql 语句的 id。该 id 可以从 v$sql.sql_id、v$session.sql_id 或者v$session.prev_sql_id 获得。如果没有指定 sql_id(指定 null),则默认会显示当前会话中最后一条执行的 sql 语句。

cursor_child_no:语句的子游标序号。我们知道,受到执行环境的影响,一条 sql 语句可能会产生多个版本的子游标,每个子游标都会与一个执行计划相映射(多个子游标也可能映射同一个执行计划)。通过 cursor_child_no 可以限制仅显示某一个子游标的执行计划。如果不指定该参数,则会显示该语句的所有子游标的执行计划。

format:格式化控制字符串。display 函数的格式化控制字符串的所有选项都 适用于 display_cursor 函 数 。 由 于 运 行 语 句 还 可 以 通 过 提 示gather_plan_statistics 或设置系统参数 statistics_level 为“all”收集语句运行的性能统计数据,因此在细化选项中还有额外的选项,以选择是否输出这些数据。

iostats:是否输出计划的输入输出(io)统计数据;

memstats:在启用了 pga 自动管理(参数 pga_aggregate_target 的值大于 0)的情况下,是否输出计划的输入内存统计数据(操作的内存使用量、内存读次数等);

allstats:包含了 iostats 和 memstats 的全部内容;

last:以上三个选项输出的统计数据都是实际产生的数据,而非估算数据,它们是该游标所有执行所产生的数据的总和。你可以增加 last 选项以限定仅显示最后一次运行的统计数据。

此外,还有一些未公布的选项可用于该函数的输出控制。首先是预定义格式:
‘advanced’:高级格式。高级格式除了会输出完全格式中的所有内容外,还会视情况输出绑定变量窥视信息和计划概要(outline)信息;
outline:是否以提示(hint)的方式显示计划概要;
peeked_binds:是否显示绑定变量窥视信息;
buffstats:是否显示内存读次数(包括一致性读和当前读次数),该信息为 iostats 的一部分;
plan_hash:是否显示计划的哈希值,该选项同样适用于 display 函数。

-- Show the execution plan in the cursor
--执行SQL
select e.last_name, d.department_name from hr.employees e,hr.departments d where e.department_id = d.department_id;

--查看执行计划
select * from table(dbms_xplan.display_cursor());

dbms_xplan.display_cursor 的 3 个参数:
1)sql_id: SQL 语句在游标缓存区的 ID。默认为 NULL,此会话中最后一条执行的语句。
2)cursor_child_no:子编号,默认为 0。
3)format: 显示格式。默认为 TYPICAL,可选 basic/typical/serial/all等。

通过 autotrace 显示计划

autotrace 是 oracle 自带 的客户 端工 具 sqlplus 的一 个特性 。启用autotrace 后,sqlplus 会自动收集执行过的语句的执行计划、性能统计数据等,并在语句执行结束后显示在 sql*plus 中。

要使用 autotrace,需要先做以下准备,用 dba 用户创建角色 plustrce,并将该角色赋予用户:

conn / as sysdba
@?/sqlplus/admin/plustrce.sql
grant plustrace to scott;

在执行语句之前,在 sql*plus 中打开 autotrace。可以在打开 autotrace时选择不同选项,以控制输出的内容。选项如下所示:
set autotrace on:打开 autotrace,并输出所有内容,包括语句本身的查询结果、执行计划,以及性能统计数据。
set autotrace on explain:打开 autotrace,并输出语句本身的查询结果和执行计划,不输出性能统计数据。
set autotrace on statistics:打开 autotrace,并输出语句本身的查询结果和性能统计数据,不输出执行计划。
set autotrace trace:打开 autotrace,并输出执行计划和性能统计数据,不输出语句本身的查询结果。
set autotrace trace explain:打开 autotrace,并输出执行计划,不输出语句本身的查询结果和性能统计数据。
set autotrace trace statistics:打开 autotrace,并输出性能统计数据,不输出语句本身的查询结果和执行计划。
set autotrace off:关闭 autotrace。

一个完整的 autotrace 报告输出包括三个部分:
第一部分为 sql 本身的执行结果;
第二部分为 sql 的执行计划;
第三部分为 sql 实际执行的性能统计数据。

由于执行计划和执行的性能数据都是进行 sql 调优时的重要参考信息,因此autotrace 是进行 sql 语句性能调优的一个非常实用的辅助方法。
当打开 autotrace 后,在执行语句之前,oracle 会调用 explain plan 命令对语句进行解析;在执行完成后,从 plan_table 中查询和显示执行计划。因此,由于受到共享游标、绑定变量窥视等设置的影响,这一执行计划可能会与实际执行计划不同。除了上述方法外,还可以通过其他一些途径获取到语句的执行计划。

四、解读执行计划

掌握了获取和显示执行计划的方法后,就可以开始了解如何来读懂一个执行计划。一个执行计划实际上是一个树状关系的结构图。在这个树状结构图中,每一个节点代表了一个操作(相应的,它们在 PLAN_TABLE、V$SQL_PLAN 等执行计划表、视图中都有一条记录),每个支节点(或者说父节点)下都有一个或多个子操作;除根节点外,每个节点都仅隶属于一个支节点。同一层操作按照它们的ID 顺序执行。操作由顶向下调用,即父操作调用子操作;数据由底向上返回,即子节点获取到的数据在处理完成后返回给父节点。

执行计划包含了相当丰富的信息。通过执行计划,不仅可以知道 SQL 引擎将以什么样的访问顺序访问对象、获取语句的输出结果,而且还可以获得优化器估算出的代价结果、运行时间以及其他一些额外信息。

exec sql_explain('select o.owner, o.object_name, o.object_id 
from t_users u, t_objects o 
where u.username=o.owner and o.object_name like :A and u.user_id=:B','BASIC PREDICATE');

在这里插入图片描述

以表格样式输出查询计划。该表有多个列,其中 ID 是计划中每个操作的唯一序列号,Operation 是每个操作的名称和方式,Name 是操作的对象。实际上,该表还有其他一些列代表了优化、统计等信息。

再看每行记录的数据,每行数据中的 Operation 都带有长短不一的前导空格使之看起来成为一个树状结构。这个结构也就是操作之间的调用关系。

首先看第一条,ID 为 0,操作为 SELECT STATEMENT。这一行实际上只表示这条语句的类型是一条 SELECT 语句,而非一个真正的操作。因此在一些执行计划的显示当中,没有显示 ID 为 0 的操作。

ID 为 1 的操作是 NESTED LOOPS,表明它需要对两个数据集以嵌套循环的方式进行数据关联。而这两个数据集则是由其两个子操作 2 和 4 分别从表 T_USERS和 T_OBJECTS 上读取得来,也就是说,操作 1 按顺序调用操作 2 和 4,获取它们返回的数据进行关联。而要实现嵌套循环,就需要两个循环体。其中,操作 2就是第一个循环体,也就是外循环;操作 4 就是第二个循环体,即内循环。

ID 为 2 的操作是 TABLE ACCESS BY INDEX ROWID,Name 是 T_USERS,表明它是通过索引上的 ROWID 来访问表 T_USERS 以获取数据。而索引上的 ROWID 则需要通过其子操作 3 来获取;

ID 为 3 的操作是 INDEX UNIQUE SCAN,Name 是 T_USERS_PK,表明它是对索引 T_USERS_PK 进行唯一键值的访问以获取其父操作所需要的 ROWID。T_USERS_PK是表 T_USERS 的主键,也是一个唯一索引。而对唯一索引的唯一键值的访问,需要有一个数值的输入作为访问条件。在它的 ID 列,我们可以留意到*符号,表示这个操作有相关的谓词条件(访问条件或者过滤条件)。而我们这里也特地显示了 谓 词 条 件 。 在下面 谓词信息输出部分 ,可以找到一条信息 3 -access(“U”.“USER_ID”=TO_NUMBER(:B)),表明这是操作 ID 为 3 的谓词条件,其中 access 表示它是访问条件,内容是通过某个数值定位 USER_ID 键值。

访问条件和过滤条件都属于谓词条件,但它们对操作的作用大不相同。访问条件可以帮助操作从物理对象上定位到符合条件的数据,然后再读取数据;而过滤条件是操作已经从物理存储上读取到了数据,然后将不符合条件的数据过滤掉。它们对语句的性能影响很大,了解了它们之间的差别,就有助于我们对语句进行进一步调优。

ID 为 4 的操作是 TABLE ACCESS FULL,Name 是 T_OBJECTS,表明它是对表T_OBJECTS 进行全表扫描。全表扫描即读取表的物理段(Segment)的高水位线(High Water Mark,HWM)以下的所有数据块。同样,它的 ID 也有*符号,从谓词信息部分可以找到关联的谓词条件 4 - filter(“O”.“OBJECT_NAME” LIKE :A
AND “U”.“USERNAME”=“O”.“OWNER”)。filter 表明它是一个过滤条件,即读取了表 T_OBJECTS 的所有数据,再过滤掉不符合条件(“O”.“OBJECT_NAME” LIKE :A AND"U".“USERNAME”=“O”.“OWNER”)的数据。

通过执行计划,可以清楚地了解一条语句是通过什么样的方式读取物理对象的数据,如何对数据进行处理(过滤、排序等),最终获取到符合条件的数据。再结合执行计划中的其他数据,可以进一步定位语句的性能瓶颈在哪里,从而为实施优化奠定基础。

在执行计划中,除了 ID、Operation 和 Name 之外,还有其他一些列。这些列的数据是根据需要从 PLAN_TABLE、V S Q L P L A N 、 V SQL_PLAN、V SQLPLANVSQL_PLAN_STATISTICS_ALL等表和视图中读取的。它们可以帮助我们进一步理解该执行计划(例如优化器对各个操作的估算数据、实际运行中各个操作的性能数据等)。以下是各个列的描述。

Rows/E-Rows:优化器估算出当前操作返回给上一级操作的数据记录数,如果计划中同时输出收集到实际记录数,则会显示为 E-Rows 以和实际记录数区别,在优化器中,又称为数据集的行数(Cardinality);

Bytes/E-Bytes:优化器估算出当前操作返回给上一级操作的数据的字节数,如果计划中同时输出收集到实际字节数,则会显示为 E-Bytes 以和实际字节数区别;

TempSpc/E-Temp:优化器估算出完成当前操作(仅部分操作需要临时空间,如 SORT、Hash Join)所需要的临时表空间的大小,如果计划中同时输出收集到实际临时空间大小,则会显示为 E-Temp 以和实际临时空间大小区别;

Cost(%CPU):优化器估算出完成当前操作的代价(包含子操作的代价),它是 IO 代价和 CPU 代价总和。其中,IO 代价是最基本的代价。而对于 CPU 代价,在默认情况下,优化器会将 CPU 代价计算在内,并且将 CPU 代价根据系统配置由特定的转换公式转换为 IO 代价。也可以通过优化器参数_optimizer_cost_model
指定是否在代价模型中包括 CPU 代价。括号中数据即为 CPU 代价在总代价中的比例;

Time/E-Time:优化器估算出完成当前操作所需要的时间,这个时间是其子操作的累计时间,如果计划中同时输出收集到实际时间,则会显示为 E-Time 以和实际时间区别;

Pstart:分区裁剪(Partition Prunning)后,访问的起始分区,仅在含有分区表访问操作的执行计划中出现;

Pstop:分区裁剪(Partition Prunning)后,访问的结束分区,仅在含有分区表访问操作的执行计划中出现;

Inst:分布式查询中,远程对象所在的数据库实例名;

TQ:并行查询中的表队列(Table Queue),我们会在相关操作中进一步阐
述该列数据;

IN-OUT:并行查询或分布式查询中数据传输方式;

PQ Distrib:并行查询中,并行服务进程之间的数据分发方式;

Starts:当前操作实际被启动的次数,如果输出格式中指定了 LAST 关键字,则为计划最后一次执行中当前操作实际被启动的次数,否则为所有被启动次数总和;

Rows:当前操作实际返回的记录数,如果输出格式中指定了 LAST 关键字,则为最后一次执行的记录数,否则为所有执行的记录数总和;

Time:执行当前操作的实际时间,如果输出格式中指定了 LAST 关键字,则为最后一次执行的时间,否则为所有执行的时间总和;

Buffers:当前操作中发生读内存的次数,如果输出格式中指定了 LAST 关键字,则为最后一次执行的读内存次数,否则为所有执行的读内存次数总和。内存读次数包括一致性读(Consistent Read,CR)和当前模式读(Current Get,CU);

Reads:当前操作中发生读磁盘的次数,如果输出格式中指定了 LAST 关键字,则为最后一次执行的读磁盘次数,否则为所有执行的读磁盘次数总和;

Writes:当前操作中发生写磁盘的次数,如果输出格式中指定了 LAST 关键字,则为最后一次执行的写磁盘次数,否则为所有执行的写磁盘次数总和;

OMem:当前操作完成所有内存工作区(Work Area)操作所总共使用私有内存(PGA)中工作区的大小。需要使用内存工作区的操作为:哈希操作,如哈希分组(Hash Group)、哈希关联(Hash Join)和排序(Sort)操作,它们分别占有工作区中哈希区(Hash Area)和排序区(Sort Area)进行工作,这个数据是由优化器统计数据以及前一次执行的性能数据估算得出的;

1Mem:当工作区大小无法满足操作所需要的大小时,需要将部分数据写入临时磁盘空间中(如果仅需要写入一次就可以完成操作,就称为一次通过,

One-Pass;否则为多次通过,Multi-Pass)。该列数据为语句最后一次执行中,单次写磁盘所需要的内存大小,这个数据是由优化器统计数据以及前一次执行的性能数据估算得出的;

Used-Mem:语句最后一次执行中,当前操作所使用的内存工作区大小,括号里面为(发生磁盘交换的次数,1 次即为 One-Pass,大于 1 次则为 Multi-Pass,如果没有使用磁盘,则显示 OPTIMAL);

Used-Tmp:语句最后一次执行中,当前操作所使用的临时段的大小,无法一次在工作区完成操作的数据被临时写入该段;

O/1/M:语句所有的执行总共使用内存或磁盘完成操作的执行次数,分别是Optimal(优化的,仅适用内存完成操作)/One-Pass/Multi-Pass;

Max-Tmp:语句所有执行中,当前操作所使用的临时段的最大空间。

通常我们所说的执行计划操作包含两个部分:操作与其选项。例如,哈希关联反关联(HASH JOIN ANTI)中,哈希关联(HASH JOIN)是一种操作,“反”关联(ANTI)则是其选项;该操作还可以与其他选项(如“半”关联,SEMI)配合形成不同的执行计划操作。

实际上,在执行计划里出现的操作包含两个信息,一个是操作类型(在PLAN_TABLE、V$SQL_PLAN 等表或视图中,字段名为 OPERATION);一个是操作的选项(在相关表和视图中,字段名为 OPTIONS)。例如 TABLE ACCESS BY INDEX ROWID,它的操作类型是 TABLE ACCESS,即访问表,选项是 BY INDEX ROWID,即通过索引中的 ROWID 来访问表。

执行计划的谓词(Predicate Information)
是查询语句中的 WHERE 子句中的过滤条件。
 Access: 表示这个谓词条件中的值将会影响数据的访问方式(表、索引、Hash等)。
 Filter:表示这个谓词条件中的值起了数据过滤的作用。

执行计划的备注(Note)
补充说明本次执行计划的内容。如:使用了动态采样、专门的查询优化技术、指
定的 SQL Profile 等。

执行计划的统计项目
在这里插入图片描述
执行计划的内容
执行计划的执行顺序:按缩行深度及 Id 顺序,一般遵循规则 " 最右最上最先 执行"。即:先从最开头一直往右看,直到看到最右边的并列的地方,对于不并列的,靠右的先执行;对于并列的,靠上的先执行。

在这里插入图片描述
Cost ( 执行计划的 开销)
Cost 是一个估算的成本量度,其中包含了对每步处理所估算的 I/O、CPU、内存等资源耗用成本。

Rows ( 基数/ 数据行数 )
在这里插入图片描述
查看每个对象是否生成正确的行数?

解决基数问题的建议 :
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1615552.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LocalAi,Ollama+AnythingLLM搭建部署本地大模型AI知识库,汉化版本

AnythingLLM 是一个全栈应用程序&#xff0c;您可以使用商业现成的 LLM 或流行的开源 LLM 和 vectorDB 解决方案来构建私有 ChatGPT&#xff0c;无需任何妥协&#xff0c;您可以在本地运行&#xff0c;也可以远程托管并能够智能聊天以及您提供的任何文件。 AnythingLLM 将您的文…

【系统架构师】-案例考点(三)

1、信息系统架构ISA设计 四种架构模型&#xff1a; 1&#xff09;单机应用 2&#xff09;客户机/服务器模式&#xff1a;两层、三层C/S、B/S模型、MVC模式等 3&#xff09;面向服务架构SOA 4&#xff09;企业数据交换总线&#xff1a;不同企业应用之间通过信息交换的公共频…

思科 Packet Tracer 实验八 DHCP基本配置(以路由为中继)

一、实验目的 了解思科网络设备的配置基本特点及 IOS 命令基本操作方法 了解DHCP的工作原理及基本配置 二、实验过程 1) 实验拓扑如下&#xff1a; 2&#xff09;由于使用DHCP‘协议动态配置ip&#xff0c;所以除了DHCP服务器和路由器接口外其他的主机&#xff0c;服务器的i…

AB5 点击消除

AB5 点击消除 可以用栈来解决。 当栈为空的时候&#xff0c;直接将字符入栈当栈非空的时候 当前字符与栈顶字符相同 出栈 当前字符与栈顶字符不同 入栈 重复上述2步即可。 栈在输出的时候不能从栈底开始输出&#xff0c;需要先把栈顶元素弹出并保存下来&#xff0c;在进行输…

过滤器Filter和拦截器Interceptor心得

上一篇文章讲了监听器Listener&#xff0c;下面我们来讲一下过滤器和拦截器。 一、过滤器Filter。 首先&#xff0c;servlet容器&#xff08;比如tomcat&#xff09;肯定的要有servlet才能发挥它的光彩。在上古jsp时代&#xff0c;我们会写各种servlet通过不同的请求来实现我…

E-MapReduce极客挑战赛季军方案

前一段时间我参加了E-MapReduce极客挑战赛&#xff0c;很幸运的获得了季军。在这把我的比赛攻略给大家分享一下&#xff0c;希望可以抛砖引玉。 赛题分析与理解 赛题背景&#xff1a; 大数据时代&#xff0c;上云已成为越来越多终端客户大数据方案的落地选择&#xff0c;阿里…

解锁EDM设计秘籍:关键要素一览,邮件如何设计?

一个成功的EDM邮件需要包含多个关键元素&#xff0c;从内容、设计到呼唤行动&#xff0c;每个环节都至关重要。今天&#xff0c;我们就来探讨EDM邮件中应包含的关键元素&#xff1f;以及如何设计邮件&#xff1f; 一、EDM必备关键要素 1、吸引眼球的主题行 主题行应该简短明了…

2-Embedding例子:简单NN网络、迁移学习例子(glove语料预训练)

一、简单例子&#xff1a;构造简单NN网络生成Embedding 1、pytorch例子 2、tensorflow例子 # 1导入模块 import tensorflow as tf from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Embedding import numpy as np# 2构建语料库 corpus[[…

【更新】cyのMemo(20240422~)

序言 胡哥首马在淮安325完赛&#xff0c;他的本硕都在淮安度过&#xff0c;七年的跑步生涯画上句号&#xff0c;真的是很圆满。七年&#xff0c;从180斤瘦到120斤&#xff0c;历经种种&#xff0c;胡哥理解的跑步&#xff0c;不是快&#xff0c;而是稳&#xff0c;他在比赛中从…

线性表的顺序存储如何设计实现?

如何存储 顺序及链式实现 计算机中的状态

【Java】变量零基础教程

目录 一、引言 二、基本组成单位 三、变量的基本原理 四、变量的基本使用步骤 五、变量快速入门 六、变量使用的注意事项 一、引言 为什么需要变量&#xff1f; ​​​​​​一个程序就是一个世界。 大家看下图&#xff0c;是我们现实中的一张生活照&#xff0c;图里有树…

汕头联想 ibm x3500 M5服务器上门维修记录

汕头联想服务器现场检修&#xff1b;汕尾IBM服务器故障维修&#xff1b;揭阳戴尔服务器维修&#xff1b;汕头ERP服务器维修&#xff1b;潮阳地区各种服务器故障维修&#xff1b;各类服务器主板齐全&#xff1b; 分享一例从东莞到汕头某染料厂维修ibm system x3500 M5服务器的真…

47.基于SpringBoot + Vue实现的前后端分离-校园外卖服务系统(项目 + 论文)

项目介绍 本站是一个B/S模式系统&#xff0c;采用SpringBoot Vue框架&#xff0c;MYSQL数据库设计开发&#xff0c;充分保证系统的稳定性。系统具有界面清晰、操作简单&#xff0c;功能齐全的特点&#xff0c;使得基于SpringBoot Vue技术的校园外卖服务系统设计与实现管理工作…

分布式技术在文本摘要生成中的应用

摘要 自然语言处理首先要应对的是如何表示文本以供机器处理&#xff0c;随着网络技术的发展和信息的公开&#xff0c;因特网上可供访问的数字文档成爆炸式的增长&#xff0c;文本摘要生成逐渐成为了自然语言处理领域的重要研究课题。本文主要介绍了分布式技术在文本摘要生成中…

Oracle21C 引入HR实例(linux)

1、下载资源 https://github.com/oracle-samples/db-sample-schemas点击code&#xff08;代码&#xff09;下载 2、上传Sql文件 解压之后将human_resources里的文件复制到demo\schema\目录&#xff08;具体目录前面的路径是你安装的路径&#xff09;下&#xff0c;如下图 3、…

argparse模块(详解)

文章目录 一、argparse模块&#xff08;1&#xff09;创建命令行解析对象&#xff1a;parser argparse.ArgumentParser()&#xff08;2&#xff09;添加命令行参数和选项&#xff1a;parser.add_argument()&#xff08;3&#xff09;解析命令行参数&#xff1a;args parser.p…

就业班 第三阶段(nginx) 2401--4.22 day1 nginx1 http+nginx初识+配置+虚拟主机

一、HTTP 介绍 HTTP协议是Hyper Text Transfer Protocol&#xff08;超文本传输协议&#xff09;的缩写,是用于从万维网&#xff08;WWW:World Wide Web &#xff09;服务器传输超文本到本地浏览器的传送协议。 HTTP是一个基于TCP/IP通信协议来传递数据&#xff08;HTML 文件…

Web3钱包开发获取测试币-Polygon Mumbai(一)

Web3钱包开发获取测试币-Polygon Mumbai(一) 由于主网区块链上的智能合约需要真正的代币&#xff0c;而部署和使用需要花费真金白银&#xff0c;因此测试网络为 Web3 开发人员提供了一个测试环境&#xff0c;用于部署和测试他们的智能合约&#xff0c;以识别和修复在将智能合约…

❤️新版Linux零基础快速入门到精通——第三部分❤️

❤️新版Linux零基础快速入门到精通——第三部分❤️ 非科班的我&#xff01;Ta&#xff01;还是来了~~~3. Linux权限管控3.1 认知root用户3.1.1 Switch User——su3.1.2 sudo命令3.1.3 为普通用户配置sudo认证 3.2 用户和用户组3.2.1 用户、用户组3.2.2 用户组管理3.2.3 用户管…

辽宁梵宁教育设计培训:赋能大学生,新技能学习再升级

辽宁梵宁教育设计培训&#xff1a;赋能大学生&#xff0c;新技能学习再升级 在当今这个日新月异、信息爆炸的时代&#xff0c;大学生们面临着前所未有的挑战与机遇。为了帮助他们更好地适应社会的快速变化&#xff0c;提升个人的综合素质和竞争力&#xff0c;辽宁梵宁教育设计…