我的理解是,嵌套循环连接的内部行源的解释计划中的估计行数反映了该嵌套循环仅一次迭代的行数。
在以下示例中,解释计划的第 6 步是嵌套循环连接的内部行源,该连接一次通过一个 ROWID 获取行。因此,估计应该有 1 行(每个 ROWID 只有 1 行)。
为什么第 6 步table access by index ROWID
显示 100(我希望它显示 1)?
使用 Oracle 19c 企业版。
drop table "C";
drop table "P";
create table "P"
( p_id NUMBER
, p_num NUMBER
, p_pad CHAR(200 byte)
)
;
insert
into "P" (p_id, p_num, p_pad)
select level
, mod(level-1,200/2)
, ' '
from dual
connect by level <= 200
;
create table "C"
( c_id NUMBER
, p_id NUMBER
, c_pad CHAR(200 byte)
)
;
insert /*+ append enable_parallel_dml parallel (auto) */
into "C" (c_id, p_id, c_pad)
with
"D" as
( select /*+ materialize */ null from dual connect by level <= 100
)
select rownum c_id
, p_id p_id
, ' ' c_pad
from "P", "D"
;
commit;
create index IX_P on p (p_num);
create unique index IU_P on p (p_id);
alter table p add constraint UK_P unique (p_id) rely using index IU_P enable validate;
alter table C add constraint R_C foreign key (p_id) references p (p_id) rely enable validate;
create index IR_C on _C (p_id);
exec dbms_stats.gather_table_stats(OwnName => null, TabName => 'P', cascade => true);
exec dbms_stats.gather_table_stats(OwnName => null, TabName => 'C', cascade => true);
select /*+ optimizer_features_enable('19.1.0')
use_nl (P C) */
*
from "P"
join "C"
on P.p_id = C.p_id
and P.p_num = 1
;
plan hash value: 3840235794
----------------------------------------------------------------------------------------------
| id | Operation | name | rows | Bytes | cost (%CPU)| time |
----------------------------------------------------------------------------------------------
| 0 | select statement | | 200 | 83000 | 205 (0)| 00:00:01 |
| 1 | nested LOOPS | | 200 | 83000 | 205 (0)| 00:00:01 |
| 2 | nested LOOPS | | 200 | 83000 | 205 (0)| 00:00:01 |
| 3 | table access by index ROWID BATCHED| P | 2 | 414 | 3 (0)| 00:00:01 |
|* 4 | index range scan | IX_P | 2 | | 1 (0)| 00:00:01 |
|* 5 | index range scan | IR_C | 100 | | 1 (0)| 00:00:01 |
| 6 | table access by index ROWID | C | 100 | 20800 | 101 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("P"."P_NUM"=1)
5 - access("P"."P_ID"="C"."P_ID")
外部行源步骤 3 乘以内部行源步骤 5 = 嵌套循环步骤 2。
但是,外部行源步骤 2 乘以内部行源步骤 6 <> 嵌套循环步骤 1。
我同意第 1 步的总数应该是 200,但不明白为什么第 6 步估计有 100 行。
为什么步骤 6 的估计行数为 100 而不是 1?
提前致谢。