12
返回列表 发新帖
楼主: zabll

对这个执行计划感觉比较迷茫,到底是要循环多少次?

[复制链接]
论坛徽章:
1
授权会员
日期:2005-10-30 17:05:33
11#
发表于 2010-4-5 17:35 | 只看该作者
prodd  有19行数据, nested loop join后的结果可以是20。例如,prodd  中的每一行可以对应prodm中的多条数据。

极端例子:
prodd的object_id 都是1, prodm的object_id 也都是1, prodd中19条数据,prodm中有10条数据,那么结果集就是19*10=190条记录了。

使用道具 举报

回复
论坛徽章:
47
蒙奇·D·路飞
日期:2017-03-27 08:04:23马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11一汽
日期:2013-09-01 20:46:27复活蛋
日期:2013-03-13 07:55:232013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:03:322012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20
12#
发表于 2010-4-5 23:44 | 只看该作者
原帖由 wqhhust 于 2010-4-5 03:35 发表
prodd  有19行数据, nested loop join后的结果可以是20。例如,prodd  中的每一行可以对应prodm中的多条数据。

极端例子:
prodd的object_id 都是1, prodm的object_id 也都是1, prodd中19条数据,prodm中有10条数据,那么结果集就是19*10=190条记录了。


You're right! Sometimes we just missed something obvious. A simple test case is what zabll provided in message #8 except the two tables should be populated as follows:

--create table t1 as select * from dba_objects where object_id<20;
create table t1 as select rownum object_id from dual connect by level < 20;

--insert into t4 select * from dba_objects;
insert into t4 (object_id) select 1 object_id from dual connect by level < 21;

The plan becomes:

---------------------------------------------------------------------------------------------
| Id  | Operation            | Name | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |      |    20 |   160 |    25   (0)| 00:00:01 |       |       |
|   1 |  NESTED LOOPS        |      |    20 |   160 |    25   (0)| 00:00:01 |       |       |
|   2 |   TABLE ACCESS FULL  | T1   |    19 |    57 |     3   (0)| 00:00:01 |       |       |
|   3 |   PARTITION RANGE ALL|      |     1 |     5 |     1   (0)| 00:00:01 |     1 |     6 |
|*  4 |    TABLE ACCESS FULL | T4   |     1 |     5 |     1   (0)| 00:00:01 |     1 |     6 |
---------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   4 - filter("T1"."OBJECT_ID"="T4"."OBJECT_ID")

So t1 has 1, 2, ..., 19, and t4 has twenty 1's. The plan says for each of the nineteen numbers (which are all distinct) in T1 (step 2), it tries to find one matching row in T4 (steps 3 and 4), and the end result is that it finds twenty in total (step 1). Actually, I'm not sure how to explain the row count 1 in steps 3 and 4. Anybody?

Yong Huang

使用道具 举报

回复
论坛徽章:
47
蒙奇·D·路飞
日期:2017-03-27 08:04:23马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11一汽
日期:2013-09-01 20:46:27复活蛋
日期:2013-03-13 07:55:232013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:03:322012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20
13#
发表于 2010-4-7 06:04 | 只看该作者
> Actually, I'm not sure how to explain the row count 1 in steps 3 and 4.

I think those two 1's are not to be trusted. Here're more accurate numbers:

SQL> select OPERATION_ID, LAST_STARTS, STARTS, LAST_OUTPUT_ROWS, OUTPUT_ROWS from v$sql_plan_statistics where sql_id = '2qp2ymfgrtq36';

OPERATION_ID  LAST_STARTS       STARTS LAST_OUTPUT_ROWS  OUTPUT_ROWS
------------ ------------ ------------ ---------------- ------------
           1            1            1               20           20
           2            1            1               19           19
           3           19           19               20           20
           4          114          114               20           20

Yong Huang

使用道具 举报

回复
论坛徽章:
1
授权会员
日期:2005-10-30 17:05:33
14#
发表于 2010-4-7 10:36 | 只看该作者
To Huang Yong

oracle的执行计划中的数据基本正确, 您所说的1, 准确的说应该是 20/19,但是oracle只精确到个位,所以是1. 在下面的第二个例子中,它就变成2了, 因为38/19=2

ORACLE@QIHUA SQL> create table t1 as select rownum a from dual connect by rownum<=19;

Table created.

ORACLE@QIHUA SQL> create table t2 as select rownum a from dual connect by rownum<=19;

Table created.

ORACLE@QIHUA SQL> insert into t2 values(10);

1 row created.

ORACLE@QIHUA SQL> commit;

Commit complete.

ORACLE@QIHUA SQL> exec dbms_stats.gather_table_stats(ownname => null,tabname => 'T1');

PL/SQL procedure successfully completed.

ORACLE@QIHUA SQL> exec dbms_stats.gather_table_stats(ownname => null,tabname => 'T2');

PL/SQL procedure successfully completed.

ORACLE@QIHUA SQL>
ORACLE@QIHUA SQL> set autotrace traceonly
ORACLE@QIHUA SQL> select /*+ leading(t1,t2) use_nl(t2,t1) */ * from t1 ,t2 where t1.a=t2.a;

20 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 3811625520

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |    20 |   120 |     8   (0)| 00:00:01 |
|   1 |  NESTED LOOPS      |      |    20 |   120 |     8   (0)| 00:00:01 |
|   2 |   TABLE ACCESS FULL| T1   |    19 |    57 |     2   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS FULL| T2   |     1 |     3 |     0   (0)| 00:00:01 |
---------------------------------------------------------------------------


ORACLE@QIHUA SQL> set autotrace off
ORACLE@QIHUA SQL>
ORACLE@QIHUA SQL> drop table t1;

Table dropped.

ORACLE@QIHUA SQL> drop table t2;

Table dropped.

ORACLE@QIHUA SQL> create table t1 as select rownum a from dual connect by rownum<=19;

Table created.

ORACLE@QIHUA SQL> create table t2 as select rownum a from dual connect by rownum<=19;

Table created.

ORACLE@QIHUA SQL> insert into t2 select * from t2;

19 rows created.

ORACLE@QIHUA SQL> commit;

Commit complete.

ORACLE@QIHUA SQL> exec dbms_stats.gather_table_stats(ownname => null,tabname => 'T1');

PL/SQL procedure successfully completed.

ORACLE@QIHUA SQL> exec dbms_stats.gather_table_stats(ownname => null,tabname => 'T2');

PL/SQL procedure successfully completed.

ORACLE@QIHUA SQL> set autotrace traceonly
ORACLE@QIHUA SQL> select /*+ leading(t1,t2) use_nl(t2,t1) */ * from t1 ,t2 where t1.a=t2.a;

38 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 3811625520

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |    38 |   228 |     8   (0)| 00:00:01 |
|   1 |  NESTED LOOPS      |      |    38 |   228 |     8   (0)| 00:00:01 |
|   2 |   TABLE ACCESS FULL| T1   |    19 |    57 |     2   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS FULL| T2   |     2 |     6 |     0   (0)| 00:00:01 |
---------------------------------------------------------------------------

使用道具 举报

回复
论坛徽章:
47
蒙奇·D·路飞
日期:2017-03-27 08:04:23马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11一汽
日期:2013-09-01 20:46:27复活蛋
日期:2013-03-13 07:55:232013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:03:322012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20
15#
发表于 2010-4-7 23:51 | 只看该作者
> 您所说的1, 准确的说应该是 20/19

Then what does the ratio 20/19 mean here? The total rows returned is 20. The top table contributes 19 rows. The number 20/19 for the bottom table means, literally, how much the top table (in ratio or percentage) has contributed to the total rows. It's still hard to associate it with some kind of row count for the bottom table.

Yong Huang

使用道具 举报

回复
论坛徽章:
4
蛋疼蛋
日期:2011-05-28 21:46:57ITPUB十周年纪念徽章
日期:2011-11-01 16:25:512012新春纪念徽章
日期:2012-01-04 11:56:44奥运会纪念徽章:跆拳道
日期:2012-09-17 11:40:43
16#
 楼主| 发表于 2010-4-8 10:38 | 只看该作者
原帖由 wqhhust 于 2010-4-7 10:36 发表
To Huang Yong

oracle的执行计划中的数据基本正确, 您所说的1, 准确的说应该是 20/19,但是oracle只精确到个位,所以是1. 在下面的第二个例子中,它就变成2了, 因为38/19=2

Table dropped.

ORACLE@QIHUA SQL> create table t1 as select rownum a from dual connect by rownum create table t2 as select rownum a from dual connect by rownum insert into t2 select * from t2;

19 rows created.

ORACLE@QIHUA SQL> commit;

Commit complete.

ORACLE@QIHUA SQL> exec dbms_stats.gather_table_stats(ownname => null,tabname => 'T1');

PL/SQL procedure successfully completed.

ORACLE@QIHUA SQL> exec dbms_stats.gather_table_stats(ownname => null,tabname => 'T2');

PL/SQL procedure successfully completed.

ORACLE@QIHUA SQL> set autotrace traceonly
ORACLE@QIHUA SQL> select /*+ leading(t1,t2) use_nl(t2,t1) */ * from t1 ,t2 where t1.a=t2.a;

38 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 3811625520

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |    38 |   228 |     8   (0)| 00:00:01 |
|   1 |  NESTED LOOPS      |      |    38 |   228 |     8   (0)| 00:00:01 |
|   2 |   TABLE ACCESS FULL| T1   |    19 |    57 |     2   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS FULL| T2   |     2 |     6 |     0   (0)| 00:00:01 |
---------------------------------------------------------------------------



Execution Plan
----------------------------------------------------------
Plan hash value: 3811625520

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |    38 |   228 |     8   (0)| 00:00:01 |
|   1 |  NESTED LOOPS      |      |    38 |   228 |     8   (0)| 00:00:01 |
|   2 |   TABLE ACCESS FULL| T1   |    19 |    57 |     2   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS FULL| T2   |     2 |     6 |     0   (0)| 00:00:01 |
---------------------------------------------------------------------------



   这个执行计划看的有点不理解,T1有19笔资料,T1中每笔资料在T2中对应有2比,但是NESTED LOOPS对应的38是什么意思?难道是循环了38次?按照道理说应该只是循环19次。

使用道具 举报

回复
论坛徽章:
1
授权会员
日期:2005-10-30 17:05:33
17#
发表于 2010-4-8 17:53 | 只看该作者
==》这个执行计划看的有点不理解,T1有19笔资料,T1中每笔资料在T2中对应有2比,但是NESTED LOOPS对应的38是什么意思?难道是循环了38次?按照道理说应该只是循环19次。
38是说NESTED LOOPS  的结果集是38行, TABLE ACCESS FULL返回19行, 当然会loop19次, 那么每次loop,能找到 2=38/19条记录。

使用道具 举报

回复
论坛徽章:
1
授权会员
日期:2005-10-30 17:05:33
18#
发表于 2010-4-8 18:00 | 只看该作者
==》Then what does the ratio 20/19 mean here?
我是说 20/19=1.0526315789473684=1. oracle总共返回20条, 循环19次,所以每次平均返回20/19=1行

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表