Oracle 12c:浪费磁盘 Space 和性能

Oracle 12c: Wasted Disk Space and Performance

我的应用程序的性质涉及每天将大型数据集删除和批量插入到 Oracle 12c 数据库中。我的 table 由日期字段间隔分区并分区索引。我使用存储过程在每个 运行 之后收集受影响分区的统计信息。最近,我发现 运行 的速度明显变慢了,想知道这是否是由于数据库的大小增加所致。

我已经搜索了如何计算我的 table 使用的总磁盘 space,通常会得出这样的结果:

select sum(bytes)/1024/1024/1024 
from dba_segments 
where owner='SCHEMA' and segment_name in ('TABLE_A', 'TABLE_B');

但是,数字很大,并不能反映实际使用的数据量。当我们导出 tables 以恢复到另一个数据库时,该文件比该查询建议的要小得多。我深入挖掘并得出了这个查询:

select partition_name, 
       blocks*8/1024 size_m, 
       num_rows*avg_row_len/1024/1024 occ_m, 
       blocks*8/1024 - num_rows*avg_row_len/1024/1024 wast_m 
from dba_tab_partitions 
where table_name='TABLE_A'; 

此查询表明有一个 "wasted" space 概念,即在执行批量插入并在再次替换数据之前删除数据后,使用的 space 不会被回收。

因此我有以下问题:

  1. "wasted" space 会导致性能下降吗? 执行 delete from table where ..?
  2. 有区别吗 执行 delete from table where .. 与丢弃相比 关于 "wasted" space?
  3. 的分区
  4. 定期执行 table 重组/碎片整理以回收 table space 是推荐的做法吗?

如果您正在执行删除或更新,您的 space 会变得支离破碎。您可以在 documentation.

中阅读相关信息

要改进您的流程,您可以执行一些清理操作,例如 shrink,或者只是在一些大插入物上重新创建 table。我的意思是,不是删除和插入,而是从旧行中创建 table as select,而不是删除行,然后将新集插入到新 table 中。之后只需交换名称并删除旧的 table.

关于你的第二个问题,我认为答案是 here。删除分区会降低 HWM 而删除不会。

Does the "wasted" space contribute to performance degradation when I perform delete from table where ..?

是的,您正在从 table 中删除 Oracle 必须在底层 table 上执行全表 Scan/Index 范围扫描(索引叶节点可能导致空块)高水位线,这会使您的删除变慢。

Is there a difference between performing a delete from table where .. as compared to dropping the partitions with regard to "wasted" space?

删除是一个缓慢的过程。它必须在图像之前创建(撤消)、更新索引、写入重做日志并删除数据。由于 DDL(Drop) 不生成 redo/undo(为元数据生成微小的 undo/redo)它会比 DML(删除)更快。

Is performing table reorganization/defragmentation on a regular basis to reclaim table space a recommended practice?

具有零碎空闲的对象 space 会导致大量浪费 space,并且会影响数据库性能。对 space 进行碎片整理和回收的首选方法是执行在线段收缩。

详情:Reclaiming Unused Space

以下博客 post 演示了 DML 期间由于浪费 space 对性能的影响以及如何消除它。

Defragmentation Can Degrade Query Performance

This query suggests that there is a "wasted" space concept where after performing bulk inserts and deleting the data before it is replaced again, the space used is not reclaimed.

这是正确的。

直接路径插入在段的高水位线上方使用 space。后续删除删除行,但不重置高水位线。

最好能够在执行另一个直接路径插入之前截断该段,因为这会重置高水位线并删除所有行。