有关块的更多信息:https://docs.oracle.com/en/database/oracle/oracle-database/21/cncpt/logical-storage-structures.html#GUID-DC561B64-67D9-43CC-A9BA-BE5B92A7B869
SELECT (SELECT COUNT (DISTINCT at.TABLE_NAME)
FROM all_tables at
JOIN dba_segments seg ON seg.BLOCKS = at.BLOCKS
WHERE at.NUM_ROWS > 0)
- (SELECT COUNT (DISTINCT at.TABLE_NAME)
FROM all_tables at
WHERE at.NUM_ROWS > 0)
FROM DUAL;
-564年我已经计算了所有具有块的表和具有nur_rows>0的表之间的差异使用所有num_row>0.
我发现它是一个负数。这意味着没有表有块。为什么。
我不能提供一个关于dbfiddle的例子:
dba_segments不存在
第一个子查询中的连接存在许多问题。
首先,当许多表具有相同数量的块时,您应该在segment_name
上连接以避免虚假匹配。
但更重要的是,这些视图的blocks
列存储了不同的信息:
*_tables.blocks
为在 表中使用的块数。*_segments.blocks
是分配给表 的块的数量。
表可以有未使用的块分配给它们。在大多数系统中,至少会有几个这样的表。
下面是一个我正在使用的数据库的例子:
select count (*) num_tables,
count ( us.segment_name ) num_segments,
count ( case when us.blocks = ut.blocks then 1 end ) equal,
count ( case when us.blocks <> ut.blocks then 1 end ) different
from user_tables ut
left join user_segments us
on table_name = segment_name
and us.segment_type = 'TABLE';
NUM_TABLES NUM_SEGMENTS EQUAL DIFFERENT
---------- ------------ ---------- ----------
457 406 51 351
请注意,大多数表都不匹配。
也有许多表没有段。这可能是因为它们还没有被分配。但也可能是因为有些表类型从未被分配段。
外部表是一个明显的例子——数据存在于数据库之外的文件中。
另一个例子是索引组织表。这里主键索引和表被组合成一个结构。所有的数据都存储在索引中;没有分配给表。
create table t (
c1 int
constraint t_pk primary key
) organization index;
insert into t
with rws as (
select level x from dual
connect by level <= 100
)
select * from rws;
commit;
exec dbms_stats.gather_table_stats ( user, 't' ) ;
select blocks from user_tables
where table_name = 'T';
BLOCKS
----------
<null>
select segment_name, segment_type, blocks
from user_segments
where segment_name in ( 'T', 'T_PK' );
SEGMENT_NAME SEGMENT_TYPE BLOCKS
-------------------- ------------------ ----------
T_PK INDEX 8