专业编程教程与实战项目分享平台

网站首页 > 技术文章 正文

Oracle数据库几千张表,如何高效查找在高水位没有回收的大表?

ins518 2024-10-22 14:42:12 技术文章 16 ℃ 0 评论

概述

很多时候数据库总有大表删除数据的情况,特别是有些是写在存储过程晚上执行的,而大表删除数据后高水位并不会回收,针对一两张表可能还要时间精力去维护,但是数据库几千张表,我们怎么去找那些在高水位没有回收的大表呢?下面介绍下对高水位表优化的思路。


思路

1、快速收集全库统计信息(开并行度)

dbms_stats.gather_database_stats(ESTIMATE_PERCENT=>DBMS_STATS.AUTO_SAMPLE_SIZE, method_opt => 'for all indexed columns', cascade=>true, degree=>8);

2、一键检查数据库高水位表

按浪费空间排序,选择前十几张大表做回收。

3、回收高水位表(shrink方式)

由于move需要额外的空间空间,而且move后需要重建索引;shrink后不需要重建索引,如果一个表的索引比较多,shrink过程中用来维护index的成本也会比较高,而且shrink不影响dml操作,能在线处理,这里选择shrink的方式来回收。

4、针对表级别重新收集统计信息

针对已经回收的表重新做统计分析。

5、验证高水位是否回收,是否减少浪费空间。


1、快速收集全库统计信息(dba用户)

1.1、开启计时

set timing on

1.2、设置并行收集

exec dbms_stats.set_global_prefs('CONCURRENT','TRUE');

1.3、开始收集全库统计信息

begin
dbms_stats.gather_database_stats(
ESTIMATE_PERCENT=>DBMS_STATS.AUTO_SAMPLE_SIZE, method_opt => 'for all indexed columns', cascade=>true, degree=>8);
end;
/

这是开并行度8时候资源情况:

1.4、关闭并行收集

exec dbms_stats.set_global_prefs('CONCURRENT','FALSE');

2、一键检查数据库高水位表

SELECT 'alter table ' || table_name || ' enable row movement;',
 'alter table ' || table_name || ' shrink space;',
 'Analyze table '|| table_name ||' COMPUTE STATISTICS;',
 table_name,
 tablespace_name,
 status,
 last_analyzed,
 ROUND((blocks * 8), 2) "高水位空间 k",
 ROUND((num_rows * avg_row_len / 1024), 2) "真实使用空间 k",
 ROUND((blocks * 10 / 100) * 8, 2) "预留空间(pctfree) k",
 ROUND((blocks * 8 - (num_rows * avg_row_len / 1024) -
 blocks * 8 * 10 / 100),
 2) "浪费空间 k"
 FROM user_tables
 WHERE temporary = 'N'
 ORDER BY 11 DESC;

3、回收高水位表

第一种方法:MOVE回收高水位(move需要额外的空间空间,move后需要重建索引)

alter table my_objects move;

第二种方法:shrink回收高水位(shrink后不需要重建索引,如果一个表的索引比较多,shrink过程中用来维护index的成本也会比较高,,shrink不影响dml操作,能在线)

alter table my_objects enable row movement;
alter table my_objects shrink space;

4、重新收集统计信息

针对表级别手动收集

ANALYZE TABLE MV_OTM_ORDER_RELEASE_LINE COMPUTE STATISTICS;

--耗时2511秒


5、测试是否回收

SELECT table_name,
 tablespace_name,
 status,
 last_analyzed,
 ROUND((blocks * 8), 2) "高水位空间 k",
 ROUND((num_rows * avg_row_len / 1024), 2) "真实使用空间 k",
 ROUND((blocks * 10 / 100) * 8, 2) "预留空间(pctfree) k",
 ROUND((blocks * 8 - (num_rows * avg_row_len / 1024) -
 blocks * 8 * 10 / 100),
 2) "浪费空间 k"
 FROM user_tables
 WHERE table_name='MV_OTM_ORDER_RELEASE_LINE';

篇幅有限,关于高水位表优化的就介绍到这了,这里提2个注意事项,1个是并行度要根据CPU数量来定(要不磁盘I/0会有问题),1个是如果用move回收要注意会消耗多一些额外空间和需要重建索引。

后面会分享更多DBA方面内容,感兴趣的朋友可以关注下!

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表