Oracle中使用alter table move命令的方法降低表中的高水位(High Water Mark)

Oracle中使用alter table move命令的方法降低表中的高水位(High Water Mark)

导读

在Oracle数据库中,"高水位"(High Water Mark)是指表中数据的存储位置已经达到的最高位置。在表中插入、更新或删除数据时,数据库会自动管理数据的存储位置,但是删除操作并不会立即释放空间,而是标记为可重用。高水位标记了表中已经被使用的存储位置的最高点,而这些位置之上的空间可以被重新利用,以存储新的数据。

当表中有大量的删除操作时,高水位可能会远远超过实际数据的位置,导致表的存储空间浪费。为了减少这种浪费,可以使用ALTER TABLE <table_name> MOVE命令来重新组织表,将高水位重新设置到实际数据的位置之上。这个操作会将表中的数据重新组织,并且释放未使用的存储空间。

需要注意的是,重新组织表可能会导致数据库性能下降,因为它需要重新组织数据并重建索引。因此,在执行此操作之前,最好在低负载时段进行,并且谨慎评估其对数据库性能的影响。

另外,有一些其他的方法也可以管理高水位,比如使用TRUNCATE TABLE来直接清空表并释放空间,或者使用ALTER TABLE <table_name> SHRINK SPACE来缩小表的存储空间。但是这些方法都可能会有一些限制或者副作用,因此在使用之前需要进行充分的了解和测试。

下面开始演示如何使用move命令来降低Oracle数据库的高水位线。

1、创建测试表test

复制代码
create table test as select * from dba_objects;

2、统计表的行数

复制代码
select count(*) from test;

  COUNT(*)
----------

581761

3、统计表的块数

复制代码
select blocks,empty_blocks,num_rows,avg_row_len from dba_tables where table_name='TEST';

    BLOCKS EMPTY_BLOCKS   NUM_ROWS AVG_ROW_LEN

---------- ------------ ---------- -----------

为空,这是因为没有搜集表的统计信息。

4、收集一下表的统计信息

复制代码
ANALYZE TABLE TEST ESTIMATE STATISTICS;

5、再次查看表的块数

复制代码
select blocks,empty_blocks,num_rows,avg_row_len from dba_tables where table_name='TEST';

BLOCKS EMPTY_BLOCKS   NUM_ROWS AVG_ROW_LEN

---------- ------------ ---------- -----------

  8026         2770     581455          97

6、查看表的高水位情况

复制代码
SELECT table_name,
       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 dba_tables
 WHERE table_name='TEST';
TABLE_NAME                     高水位空间 k 真实使用空间 k 预留空间(pctfree) k 浪费空间 k

------------------------------ ------------ -------------- ------------------- ----------

TEST                                  64208       55079.23              6420.8    2707.97

7、删除399999条记录

复制代码
DELETE FROM TEST WHERE ROWNUM<400000;

399999 rows deleted.

COMMIT;

8、查看表的块数

复制代码
select blocks,empty_blocks,num_rows,avg_row_len from dba_tables where table_name='TEST';

BLOCKS EMPTY_BLOCKS   NUM_ROWS AVG_ROW_LEN

---------- ------------ ---------- -----------

  8026         2770     581455          97

块数和行数均没有发生变化,是因为没有收集表的统计信息

9、收集表的统计信息

复制代码
ANALYZE TABLE TEST ESTIMATE STATISTICS;

10、再次查看表的块数和行数

复制代码
select blocks,empty_blocks,num_rows,avg_row_len from dba_tables where table_name='TEST';

BLOCKS EMPTY_BLOCKS   NUM_ROWS AVG_ROW_LEN

---------- ------------ ---------- -----------

  8026         2770     170975          97

表的块数没有发生变化(高水位),表的行数减少了399999行。

11、降低高水位

复制代码
ALTER TABLE TEST MOVE;

12、查看表的块数

复制代码
select blocks,empty_blocks,num_rows,avg_row_len from dba_tables where table_name='TEST';

BLOCKS EMPTY_BLOCKS   NUM_ROWS AVG_ROW_LEN

---------- ------------ ---------- -----------

  8026         2770     170975          97

表的块数没有降低

13、收集一下表的统计信息

复制代码
ANALYZE TABLE TEST ESTIMATE STATISTICS;

14、再次查看表的块数

复制代码
select blocks,empty_blocks,num_rows,avg_row_len from dba_tables where table_name='TEST';

BLOCKS EMPTY_BLOCKS   NUM_ROWS AVG_ROW_LEN

---------- ------------ ---------- -----------

  2351          852     171822          96

表的块数已经降低了。

15、查看表的高水位情况

复制代码
SELECT table_name,
       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 dba_tables
 WHERE table_name='TEST';
TABLE_NAME                     高水位空间 k 真实使用空间 k 预留空间(pctfree) k 浪费空间 k

------------------------------ ------------ -------------- ------------------- ----------

TEST                                  18808       16108.31              1880.8     818.89
相关推荐
广州智造3 小时前
OptiStruct实例:3D实体转子分析
数据库·人工智能·算法·机器学习·数学建模·3d·性能优化
技术宝哥6 小时前
Redis(2):Redis + Lua为什么可以实现原子性
数据库·redis·lua
学地理的小胖砸7 小时前
【Python 操作 MySQL 数据库】
数据库·python·mysql
dddaidai1238 小时前
Redis解析
数据库·redis·缓存
数据库幼崽8 小时前
MySQL 8.0 OCP 1Z0-908 121-130题
数据库·mysql·ocp
Amctwd8 小时前
【SQL】如何在 SQL 中统计结构化字符串的特征频率
数据库·sql
betazhou9 小时前
基于Linux环境实现Oracle goldengate远程抽取MySQL同步数据到MySQL
linux·数据库·mysql·oracle·ogg
lyrhhhhhhhh9 小时前
Spring 框架 JDBC 模板技术详解
java·数据库·spring
喝醉的小喵10 小时前
【mysql】并发 Insert 的死锁问题 第二弹
数据库·后端·mysql·死锁
付出不多11 小时前
Linux——mysql主从复制与读写分离
数据库·mysql