我的应用程序的性质涉及每天删除大量数据集并将其大量插入Oracle 12c数据库。我的表由日期字段进行间隔分区,并进行分区索引。我使用存储过程在每次运行后收集受影响分区的统计信息。最近,我发现运行速度已经大大减慢,并且想知道这是否是由于数据库的大小增加。
我已经搜索了如何计算我的表使用的总磁盘空间,并且通常会到达:
select sum(bytes)/1024/1024/1024
from dba_segments
where owner='SCHEMA' and segment_name in ('TABLE_A', 'TABLE_B');
但是,这些数字很大,并不反映实际使用的数据量。当我们将表还原到另一个数据库时,该文件比查询建议的要小得多。我深入挖掘并改为查询:
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';
此查询表明存在浪费"空间概念在执行批量插入并在再次替换之前删除数据之后,不会回收使用的空间。
因此,我有以下问题:
delete from table where ..
?delete from table where ..
关于"浪费的分区"空间?答案 0 :(得分:1)
如果你正在删除或更新你的空间正在变得支离破碎。您可以在documentation中了解相关信息。
要改进您的流程,您可以执行某些清理操作,例如shrink,或者只是在某些大插页上重新创建表格。我的意思是,而不是做删除和插入do create table as old from old where row to delete,然后将new set插入到新表中。之后只需交换名称并删除旧表。
关于你的第二个问题,我认为答案是here。删除分区将减少HWM,删除则不会。
答案 1 :(得分:1)
"浪费了#34;当我从表中执行删除时空间导致性能下降...?
是的,您要从表中删除Oracle必须在基础表上执行完全Tabl扫描/索引范围扫描(索引叶节点可能导致空块),直到高水位标记,这会使您的删除速度变慢。
执行从表中删除的位置与删除分区之间的差异是什么?#34;浪费"空间?
删除是一个缓慢的过程。它必须在映像之前创建(撤消),更新索引,写入重做日志并删除数据。由于DDL(Drop)不会生成重做/撤消(为元数据生成微小的撤消/重做),它会比DML(删除)更快。
是否定期执行表重组/碎片整理以回收表空间建议的做法?
具有碎片可用空间的对象可能导致大量浪费的空间,并可能影响数据库性能。对这个空间进行碎片整理和回收的首选方法是执行在线段缩小。
以下博客文章阐述了DML期间对性能的影响,因为浪费了空间以及如何摆脱它。
答案 2 :(得分:0)
此查询表明存在“浪费”空间概念,在再次替换之前执行批量插入和删除数据后,不会回收使用的空间。
这是正确的。
直接路径插入使用段的高水位线上方的空间。后续删除删除行,但不重置高水位线。
最好能够在执行另一个直接路径插入之前截断该段,因为这会重置高水位线并删除所有行。