oracle 执行操持详解

打印 上一主题 下一主题

主题 1795|帖子 1795|积分 5385

执行操持是指示 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 (默认值)
检察参数:
  1. SQL> show parameter optimizer_mode
复制代码
在同一体系环境下,同一条 SQL 语句选用差别的优化模式,将可能令优化器天生差别的执行操持。
修改 CBO 优化 模式:
(1)Sessions 级别:
  1. SQL> alter session set optimizer_mode = all_rows;
复制代码
(2)体系级别:修改 spfile 参数
  1. SQL> alter system set OPTIMIZER_MODE = ALL_ROWS;
复制代码
(3)语句级别:用 Hint(/*+ … */)来设定
  1. SQL> Select /*+ first_rows(10) */ name from table;
复制代码
二、SQL 语句的执行过程

用户发出待执行的 SQL 语句 -> 解析 -> 优化器(查询转换,RBO 或 CBO处理)-> 天生执行操持 -> 现实执行 -> 返回效果。

处理步骤包括:
1、语法检查(syntax check): 检查此 sql 的拼写是否语法。例如:
  1. SELECT * FORM employees;
复制代码
2、语义检查(semantic check): 访问对象是否存在及该用户是否具备相应的权限。例如:
  1. 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。
  1. SQL>alter system flush shared_pool;
  2. SQL>create table test as select * from dba_objects where 1<>1;
  3. --收集 test 表统计信息
  4. SQL>exec dbms_stats.gather_table_stats('sys','test');
复制代码
下面语句为硬解析:
  1. SQL>select * from test where object_id=20;
  2. SQL>select * from test where object_id=30;
  3. SQL>select * from test where object_id=40;
  4. SQL>select * from test where object_id=50;
复制代码
下面语句为软件解析:
  1. var oid number
  2. exec :oid:=20;
  3. select * from test where object_id=:oid;
  4. exec :oid:=30;
  5. select * from test where object_id=:oid;
  6. exec :oid:=40;
  7. select * from test where object_id=:oid;
  8. exec :oid:=50;
  9. select * from test where object_id=:oid;
复制代码
下面语句为软软解析:
  1. declare
  2. i number;
  3. begin
  4. for i in 1..14 loop
  5. execute immediate 'select * from test where object_id=:i' using i;
  6. end loop;
  7. end;
  8. /
复制代码
查询语句执行情况:
  1. col sql_text format a40
  2. 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;
  3. SQL_TEXT                              PARSE_CALLS   LOADS   EXECUTIONS
  4. ------------------------------------- ----------- ---------- ----------
  5. select * from test where object_id=20 1            1              1
  6. select * from test where object_id=30 1            1              1
  7. select * from test where object_id=40 1            1              1
  8. select * from test where object_id=50 1            1              1
  9. select * from test where object_id=:i 1            1              14
  10. select * from test where object_id=:oid 4         1             4
复制代码
设置 cursor_sharing 参数为 force,设置为 force 后,oracle 将 2 条类似的SQL 的谓词用一个变量取代,同时将它们看做同一条 SQL 语句处理。这种方式很粗暴,但极可能造成执行操持的不正确。实用场景:在无法将应用的代码修改为绑定变量情况下,oracle 提供的一种解决方法。
  1. alter system flush shared_pool;
  2. alter session set cursor_sharing=force;
复制代码
查询语句:
  1. select * from test where object_id=60;
  2. select * from test where object_id=70;
  3. select * from test where object_id=80;
  4. select * from test where object_id=90;
  5. select * from test where object_id=100;
  6. select * from test where object_id=110;
复制代码
查询语句执行情况:
  1. col sql_text format a50
  2. select sql_id,child_number,sql_text,buffer_gets
  3. 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 的操纵。
  1. --生成执行计划
  2. explain plan for select * from scott.dept;
  3. --典型格式输出执行计划,即默认 typical 格式输出
  4. select * from table(dbms_xplan.display());
  5. ---------------------------------------------
  6. |Id| Operation        | Name | Rows | Bytes | Cost (%CPU)| Time     |
  7. --------------------------------------------------------------------
  8. |0 | SELECT STATEMENT |      | 4    | 80    | 3 (0)      | 00:00:01 |
  9. |1 | TABLE ACCESS FULL| DEPT | 4    | 80    | 3 (0)      | 00:00:01 |
  10. --------------------------------------------------------------------
  11. --基本格式输出执行计划,包括 ROWS BYTES
  12. select * from table(dbms_xplan.display(null,null,'BASIC ROWS BYTES'));
  13. -----------------------------------------------
  14. | Id | Operation        | Name | Rows | Bytes |
  15. -----------------------------------------------
  16. | 0  | SELECT STATEMENT |      | 4    | 80    |
  17. | 1  | TABLE ACCESS FULL| DEPT | 4    | 80    |
  18. -----------------------------------------------
  19. --基本格式输出执行计划,包括 ROWS BYTES COST
  20. select * from table(dbms_xplan.display(null,null,'BASIC ROWS BYTES COST'));
  21. ---------------------------------------------------------------
  22. | Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
  23. ---------------------------------------------------------------
  24. | 0 | SELECT STATEMENT | | 4 | 80 | 3 (0)|
  25. | 1 | TABLE ACCESS FULL| DEPT | 4 | 80 | 3 (0)|
  26. ---------------------------------------------------------------
  27. --典型格式输出执行计划
  28. select * from table(dbms_xplan.display(null,null,'TYPICAL'));
  29. -----------------------------------------------------------------
  30. |Id|Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
  31. -----------------------------------------------------------------
  32. |0| SELECT STATEMENT | | 4 | 80 | 3 (0)| 00:00:01 |
  33. |1| TABLE ACCESS FULL| DEPT | 4 | 80 | 3 (0)| 00:00:01 |
  34. -----------------------------------------------------------------
  35. --屏蔽 rows
  36. select * from table(dbms_xplan.display(null,null,'TYPICAL -rows'));
  37. -----------------------------------------------------------------
  38. | Id | Operation | Name | Bytes | Cost (%CPU)| Time |
  39. -----------------------------------------------------------------
  40. | 0 | SELECT STATEMENT | | 80 | 3 (0)| 00:00:01 |
  41. | 1 | TABLE ACCESS FULL| DEPT | 80 | 3 (0)| 00:00:01 |
  42. -----------------------------------------------------------------
复制代码
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 函数。
  1. -- Show the execution plan in the cursor
  2. --执行SQL
  3. select e.last_name, d.department_name from hr.employees e,hr.departments d where e.department_id = d.department_id;
  4. --查看执行计划
  5. 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,并将该角色赋予用户:
  1. conn / as sysdba
  2. @?/sqlplus/admin/plustrce.sql
  3. 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 引擎将以什么样的访问次序访问对象、获取语句的输出效果,而且还可以获得优化器估算出的代价效果、运行时间以及其他一些额外信息。
  1. exec sql_explain('select o.owner, o.object_name, o.object_id
  2. from t_users u, t_objects o
  3. 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                  SQLP​LAN、VSQL_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 ( 基数/ 数据行数 )

检察每个对象是否天生正确的行数?
解决基数问题的发起 :


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

魏晓东

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表