集群中表的执行计划在应预期多个时期待一行

问题描述 投票:0回答:1

我已使用以下定义在集群中创建了一个集群和一个表:

create cluster roald_dahl_titles (
   title varchar2(100)
);

create index i_roald_dahl_titles
on cluster roald_dahl_titles
;

create table ROALD_DAHL_NOVELS (
   title varchar2(100),
   published_year number
)
cluster roald_dahl_titles (title)
;

[值得注意的是,此索引不是使用唯一约束创建的,很可能在表ROALD_DAHL_NOVELS中插入重复的值:

insert into roald_dahl_novels (title, published_year) values ('Esio Trot', 1990);
insert into roald_dahl_novels (title, published_year) values ('Esio Trot', 1990);

然后,我收集表和索引的统计信息,并查看使用索引的执行计划:

begin
  dbms_stats.gather_table_stats(user, 'ROALD_DAHL_NOVELS');
  dbms_stats.gather_INDEX_stats(user, 'I_ROALD_DAHL_TITLES');
end;
/

explain plan for
select published_year
  from roald_dahl_novels
 where title = 'Esio Trot';

select *
  from table(dbms_xplan.display(format => 'ALL'));

尽管执行计划的内容有些混乱,但是:

Plan hash value: 2187850431

--------------------------------------------------------------------------------------------
| Id  | Operation            | Name                | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |                     |     2 |    28 |     1   (0)| 00:00:01 |
|   1 |  TABLE ACCESS CLUSTER| ROALD_DAHL_NOVELS   |     2 |    28 |     1   (0)| 00:00:01 |
|*  2 |   INDEX UNIQUE SCAN  | I_ROALD_DAHL_TITLES |     1 |       |     0   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------

Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------

   1 - SEL$1 / ROALD_DAHL_NOVELS@SEL$1
   2 - SEL$1 / ROALD_DAHL_NOVELS@SEL$1

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

   2 - access("TITLE"='Esio Trot')

Column Projection Information (identified by operation id):
-----------------------------------------------------------

   1 - "ROALD_DAHL_NOVELS".ROWID[ROWID,10], "TITLE"[VARCHAR2,100], 
       "PUBLISHED_YEAR"[NUMBER,22]
   2 - "ROALD_DAHL_NOVELS".ROWID[ROWID,10]

作为操作2的一部分,它执行索引唯一扫描,这告诉我'Esio Trot'预期在群集中仅出现一次。执行计划还说,对于该操作,它只希望返回一行。

列投影信息告诉我,它希望返回单个列(这将是表ROALD_DAHL_NOVELS的ROWID),所以这告诉我从该操作返回的ROWID总数将为1(第1行为1每行ROWID)。由于表ROALD_DAHL_NOVELS的两行中的每一行都有不同的ROWID,因此此操作只能用于返回表中的单行。

当执行TABLE ACCESS CLUSTER操作时,执行计划然后(正确)期望返回两行,这让我感到困惑。如果ROWID正在访问这些行,那么我希望上一个操作返回(至少)两个ROWID。如果ROWID未访问它们,则我不希望先前的操作返回ROWID。

[此外,在表访问群集中,表ROALD_DAHL_NOVELS的ROWID在列投影信息部分中列出。我没有尝试选择ROWID,所以我不希望它从该操作返回。如果可以的话,我希望它会在谓词信息部分中。

sql oracle sql-execution-plan
1个回答
0
投票

实际执行计划存在相同的问题(在19.5中进行了测试)。也许这是显示的集群目标执行计划的限制或错误。

SQL> select *
  2  from   dbms_xplan.display_cursor(null, null, 'ALL ALLSTATS LAST');

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  f41cf1x2zdyyr, child number 0
-------------------------------------
select published_year   from roald_dahl_novels  where title = 'Esio
Trot'

Plan hash value: 2187850431

--------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation        | Name        | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |
--------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |              |   1 |        |       |     1 (100)|      |      2 |00:00:00.01 |       3 |
|   1 |  TABLE ACCESS CLUSTER| ROALD_DAHL_NOVELS   |      1 |      2 |    28 |     1   (0)| 00:00:01 |      2 |00:00:00.01 |       3 |
|*  2 |   INDEX UNIQUE SCAN  | I_ROALD_DAHL_TITLES |      1 |      1 |       |     0   (0)|      |      1 |00:00:00.01 |       1 |
--------------------------------------------------------------------------------------------------------------------------------------

Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------

   1 - SEL$1 / ROALD_DAHL_NOVELS@SEL$1
   2 - SEL$1 / ROALD_DAHL_NOVELS@SEL$1

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

   2 - access("TITLE"='Esio Trot')

Column Projection Information (identified by operation id):

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------

   1 - "ROALD_DAHL_NOVELS".ROWID[ROWID,10], "TITLE"[VARCHAR2,100], "PUBLISHED_YEAR"[NUMBER,22]
   2 - "ROALD_DAHL_NOVELS".ROWID[ROWID,10]


32 rows selected.
© www.soinside.com 2019 - 2024. All rights reserved.