关于执行计划中的%CPU的含义

今天突然想起前段时间学习的一篇博客,是oaktable的Charles Hooper所写,链接为:
https://hoopercharles.wordpress.com/2010/02/19/what-is-the-meaning-of-the-cpu-column-in-an-explain-plan/
自己也趁机消化了一下。对于执行计划中的 列Cost (%CPU),其中的%CPU的含义很少有人能够说得清楚,于是Charles Hooper写了上面的文章来解释。
对于执行计划的信息都会放入plan_table,所以对于plan_table中存在的三个列,也是需要格外关心的。
我也顺便从官方文档中查看了cost,cpu_cost,io_cost在10g,11g中的解释,发现还是有很大的差别,10g版本中只是寥寥几笔带过,11g中的问当描述就要详细的多。

11g 10g
COST Cost of the operation as estimated by the
optimizer's query approach. Cost is not determined for table access
operations. The value of this column does not have any particular unit of
measurement; it is merely a weighted value used to compare costs of execution
plans. The value of this column is a function of the CPU_COST and IO_COST columns.
Cost of the current operation estimated by the
cost-based optimizer (CBO)
CPU_COST CPU cost of the operation as estimated by the
query optimizer's approach. The value of this column is proportional to the
number of machine cycles required for the operation. For statements that use
the rule-based approach, this column is NULL
User-defined
CPU cost
IO_COST I/O cost of the operation as estimated by the
query optimizer's approach. The value of this column is proportional to the
number of data blocks read by the operation. For statements that use the
rule-based approach, this column is NULL.
User-defined
CPU cost

对于%CPU的计算方式,还是根据CBO模型估算的值,我就不按照这位大师的方式了。自己准备了一些数据也来简单模拟一下。
首先创建两个表,一个大表,一个小表。
create table test_big as select object_id,object_name from all_objects;
create table test_small as select object_id,object_name from all_objects where rownum<10;
收集统计信息
exec dbms_stats.gather_table_stats(OWNNAME=>null,tabname=>'TEST_BIG',cascade=>TRUE);
exec dbms_stats.gather_table_stats(OWNNAME=>null,tabname=>'TEST_SMALL',cascade=>TRUE);
然后开始得到执行计划的信息
explain plan for select big.object_id from test_big big,test_small small where big.object_id=small.object_id order by big.object_id;
查看执行计划信息如下:
SQL> select *from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------------
Plan hash value: 714063251
----------------------------------------------------------------------------------
| Id  | Operation           | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |            |     9 |    72 |   104   (2)| 00:00:02 |
|   1 |  SORT ORDER BY      |            |     9 |    72 |   104   (2)| 00:00:02 |
|*  2 |   HASH JOIN         |            |     9 |    72 |   103   (1)| 00:00:02 |
|   3 |    TABLE ACCESS FULL| TEST_SMALL |     9 |    27 |     3   (0)| 00:00:01 |
|   4 |    TABLE ACCESS FULL| TEST_BIG   | 72872 |   355K|    99   (0)| 00:00:02 |
----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("BIG"."OBJECT_ID"="SMALL"."OBJECT_ID")
16 rows selected.
这个时候可以看到在有些行中显示%CPU为1,有些为2.
我们来看看plan_table中的结果。
SELECT
  ID,
  COST,
  IO_COST,
  CPU_COST
FROM
  PLAN_TABLE;
结果如下:
        ID       COST    IO_COST   CPU_COST
---------- ---------- ---------- ----------
         0        104        102   69336070
         1        104        102   69336070
         2        103        102   36982117
         3          3          3      29836
         4         99         99   13487397
至于%CPU的计算方式,可以参考下面的例子。
SELECT
  ID,
  COST,
  IO_COST,
  COST-IO_COST DIFF,
  CEIL(DECODE(COST,0,0,(COST-IO_COST)/COST)*100) PER_CPU,
  CPU_COST
FROM
  PLAN_TABLE;
        ID       COST    IO_COST       DIFF    PER_CPU   CPU_COST
---------- ---------- ---------- ---------- ---------- ----------
         0        104        102          2          2   69336070
         1        104        102          2          2   69336070
         2        103        102          1          1   36982117
         3          3          3          0          0      29836
         4         99         99          0          0   13487397
可以看到在id=0的行 %CPU为2,id=2的行,%CPU为1
这些也是完全和执行计划吻合的。
再来看一个例子,我们开启一个并行查询。
SQL> explain plan for select /*+parallel*/ *from test_big ;
Explained.
这个时候直接查看plan_table的结果,来猜猜执行计划的情况。
SQL> SELECT
      ID,
      COST,
      IO_COST,
      COST-IO_COST DIFF,
      CEIL(DECODE(COST,0,0,(COST-IO_COST)/COST)*100) PER_CPU,
      CPU_COST
    FROM
      PLAN_TABLE;
        ID       COST    IO_COST       DIFF    PER_CPU   CPU_COST
---------- ---------- ---------- ---------- ---------- ----------
         0         55         55          0          0    6882356
         1
         2         55         55          0          0    6882356
         3         55         55          0          0    6882356
         4         55         55          0          0    6882356
再次查看执行计划的情况。
SQL> select *from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------------------------------
Plan hash value: 2497108266
--------------------------------------------------------------------------------------------------------------
| Id  | Operation            | Name     | Rows  | Bytes | Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
--------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |          | 72872 |  2063K|    55   (0)| 00:00:01 |        |      |            |
|   1 |  PX COORDINATOR      |          |       |       |            |          |        |      |            |
|   2 |   PX SEND QC (RANDOM)| :TQ10000 | 72872 |  2063K|    55   (0)| 00:00:01 |  Q1,00 | P->S | QC (RAND)  |
|   3 |    PX BLOCK ITERATOR |          | 72872 |  2063K|    55   (0)| 00:00:01 |  Q1,00 | PCWC |            |
|   4 |     TABLE ACCESS FULL| TEST_BIG | 72872 |  2063K|    55   (0)| 00:00:01 |  Q1,00 | PCWP |            |
--------------------------------------------------------------------------------------------------------------
Note
-----
   - automatic DOP: Computed Degree of Parallelism is 2
可以看到官方文档中对于cost的解释最后一句The value of this column is a function of the CPU_COST and IO_COST columns.
看来还是很有必要来分析分析这个function是怎么回事了。

时间: 2024-10-14 05:59:17

关于执行计划中的%CPU的含义的相关文章

执行计划中各字段各模块描述

      在SQL语句的执行计划中,包含很多字段项和很多模块,其不同字段代表了不同的含义且在不同的情形下某些字段.模块显示或不显示,下面的描述给出了执行计划中各字段的含义以及各模块的描述.        有关执行计划中各字段模块的描述请参考: 执行计划中各字段各模块描述        有关由SQL语句来获取执行计划请参考:     使用 EXPLAIN PLAN 获取SQL语句执行计划        有关使用autotrace来获取执行计划请参考:启用 AUTOTRACE 功能       有

《Oracle高性能SQL引擎剖析:SQL优化与调优机制详解》一2.5 执行计划中其他信息的含义

2.5 执行计划中其他信息的含义 通过DBMS_XPLAN输出执行计划,除了计划本身外,还可以获得一些其他信息帮助我们进一步分析执行计划及语句性能. 2.5.1 查询块和对象别名 在使用DBMS_XPLAN显示执行计划时,选择'ADVANCED'预定义格式作为参数或者加入'ALIAS'控制字符串,可以在输出中看到以下内容: Query Block Name / Object Alias (identified by operation id): -------------------------

执行计划中常见index访问方式(转)

近期有朋友对于单个表上的index各种情况比较模糊,这里对于单个表上,单个index出现的大多数情况进行了总结性测试,给出了测试结果,至于为什么出现这样的试验结果未做过多解释,给读者留下思考的空间.本篇文章仅仅是为了测试hint对index的影响,而不是说明走各种index方式的好坏.参考: INDEX FULL SCAN vs INDEX FAST FULL SCAN创建表模拟测试 SQL> create table t_xifenfei as select object_id,object_

通过执行计划中的CONCATENATION分析sql问题

昨天开发的一个同事找到我,说写了一条sql语句,但是执行了半个小时还没有执行完,想让我帮忙看看是怎么回事. 他大体上给我讲了下逻辑,表bl1_rc_rates是千万级数据量的表,autsu_subscriber 是个临时表,里面只有三百多条数据,bl1_activity_history 表的数据量略小,是百万级的.    select distinct hist.entity_id, rc.* from bl1_activity_history hist, bl1_rc_rates rc, au

浅析SQL SERVER执行计划中的各类怪相

在查看执行计划或调优过程中,执行计划里面有些现象总会让人有些疑惑不解:     1:为什么同一条SQL语句有时候会走索引查找,有时候SQL脚本又不走索引查找,反而走全表扫描?     2:同一条SQL语句,查询条件的取值不同,它的执行计划会一致吗?     3: 同一条SQL语句,其执行计划会变化,为什么     4: 在查询条件的某个或几个字段上创建了索引,执行计划就一定会走该索引吗?     5:同时存在几个索引,SQL语句会走那个索引?      .....................

FAQ系列 | EXPLAIN执行计划中要重点关注哪些要素

导读 EXPLAIN的结果中,有哪些关键信息值得注意呢? MySQL的EXPLAIN当然和ORACLE的没法比,不过我们从它输出的结果中,也可以得到很多有用的信息. 总的来说,我们只需要关注结果中的几列: 列名 备注 type 本次查询表联接类型,从这里可以看到本次查询大概的效率 key 最终选择的索引,如果没有索引的话,本次查询效率通常很差 key_len 本次查询用于结果过滤的索引实际长度,参见另一篇分享(FAQ系列-解读EXPLAIN执行计划中的key_len) rows 预计需要扫描的记

FAQ系列 | 解读EXPLAIN执行计划中的key_len

导读 EXPLAIN中的key_len一列表示什么意思,该如何解读? EXPLAIN执行计划中有一列 key_len 用于表示本次查询中,所选择的索引长度有多少字节,通常我们可借此判断联合索引有多少列被选择了. 在这里 key_len 大小的计算规则是: 一般地,key_len 等于索引列类型字节长度,例如int类型为4-bytes,bigint为8-bytes: 如果是字符串类型,还需要同时考虑字符集因素,例如:CHAR(30) UTF8则key_len至少是90-bytes: 若该列类型定义

执行计划中的COLLECTION ITERATOR PICKLER FETCH导致的性能问题

今天开发的同事找到我,让我评估一个sql语句.因为这条语句被应用监控组给抓取出来了,需要尽快进行性能调优. sql语句比较长,是由几个Union连接起来的子查询. xxxxx UNION   SELECT /*+ leading (ar1_creditid_tab ar1_unapplied_credit) use_nl (ar1_creditid_tab ar1_unapplied_credit) */            UNIQUE            0,            MA

执行计划变化导致CPU负载高的问题分析

前几天碰到一个CPU负载较高的问题.从系统层面来看,情况不是很严重,但是从应用的角度来说,已经感觉到很慢了.因为前端的调用频率还是比较高.所以会把这个问题放大. 使用top -c查看了基本的服务器信息.可以看到负载大概在30%左右.IO wait不高. top - 19:30:48 up 179 days,  4:54,  3 users,  load average: 4.43, 4.28, 4.14 Tasks: 669 total,   6 running, 661 sleeping,