我已使用以下定义在集群中创建了一个集群和一个表:
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,所以我不希望它从该操作返回。如果可以的话,我希望它会在谓词信息部分中。
实际执行计划存在相同的问题(在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.