一、产生原因:
表产生大量碎片,是因为在delete引起的。delete 删除表并没有回收高水位线
查询表碎片化程度的查语句:
–查找碎片化程度较高的表
SELECT * FROM (
SELECT
TABLE_NAME,
(BLOCKS8192/1024/1024) AS HWH_MB, --已占用大小(高水位线)
(NUM_ROWSAVG_ROW_LEN/1024/1024) AS USED_MB , --实际大小
ROUND((NUM_ROWSAVG_ROW_LEN/1024/1024)/(BLOCKS8192/1024/1024),3) AS USED_RATE --实际使用率
FROM USER_TABLES WHERE BLOCKS >0
)
WHERE USED_RATE <0.3 (使用率不到30%)
二:演示步骤
1.创建表并插入数据
(1)创建表
create table T3(id int, major varchar(255));
(2)创建插入数据的存储过程 插入100万条数据
CREATE OR REPLACE PROCEDURE P_INSERT_T3 AS
I INT DEFAULT 1;
BEGIN
FOR I IN 1 … 1000000 LOOP
INSERT INTO T3 (ID, MAJOR) VALUES (I, ‘金融学院-’ || I);
END LOOP;
COMMIT;
END;
(3)调用存储过程,插入1亿条数据
BEGIN
P_INSERT_T3;
END;
(4)同时建立索引
create index idx_T3_id on T3( id);
(5)统计表T3的信息
这里的CDM表示用户名 ,T3表示表名
BEGIN
dbms_stats.gather_table_stats(‘CDM’,‘T3’,CASCADE=>TRUE);
END;
analyze table T3 compute statistics;
(6)查看表的数据信息
6.1查询表使用的块、空块、行数
SELECT blocks, empty_blocks, num_rows FROM user_tables WHERE table_name =‘T3’;
– blocks 4150
– empty_blocks 74
– num_rows 1000000
6.2查看表段大小
select sum(bytes)/1024/1024 from USER_segments where segment_name=‘T3’; --33m
6.3 查看表的索引段大小
select sum(bytes)/1024/1024 from USER_segments where segment_name=‘IDX_T3_ID’; --18m
6.4查询表的空间使用情况
SELECT
TABLE_NAME,
(BLOCKS * 8192 / 1024 / 1024) “高水位空间MB”,
(NUM_ROWS * AVG_ROW_LEN / 1024 / 1024) “已用空间MB”,
blocks10/1008192/1024/1024 “预留空间MB(pctfree)”,
(BLOCKS * 8192 / 1024 / 1024)-(NUM_ROWS * AVG_ROW_LEN / 1024 / 1024)-(blocks10/1008192/1024/1024) “浪费空间MB”
FROM USER_TABLES
WHERE table_name = ‘T3’;
(7)执行执行计划,查看查询语句的CPU消耗情况
explain plan for select * from T3 ;
commit;
select * from table(dbms_xplan.display);
2.删除表之后
(1).删除表:
delete from T3 where id>3000;
commit;
select count(*) from T3; --3000
(2)统计表信息并查看
–执行删除操作之后分析表
BEGIN
dbms_stats.gather_table_stats(‘CDM’,‘T3’,CASCADE=>TRUE);
END;
analyze table T3 compute statistics;
–执行下面语句发现,已使用的块和空块都没有变少,跟删除之前一样,只是行数变少了
SELECT blocks, empty_blocks, num_rows FROM user_tables WHERE table_name =‘T3’;
– blocks 4150
– empty_blocks 74
– num_rows 3000
–执行下面语句发现,高水位线还是跟之前一致,已用空间变少了,但是浪费的空间变多了
SELECT
TABLE_NAME,
(BLOCKS * 8192 / 1024 / 1024) “高水位空间MB”,
(NUM_ROWS * AVG_ROW_LEN / 1024 / 1024) “已用空间MB”,
blocks10/1008192/1024/1024 “预留空间MB(pctfree)”,
(BLOCKS * 8192 / 1024 / 1024)-(NUM_ROWS * AVG_ROW_LEN / 1024 / 1024)-(blocks10/1008192/1024/1024) “浪费空间MB”
FROM USER_TABLES
WHERE table_name = ‘T3’;
(3)查看执行计划的消耗
–删除表之后查看执行计划消耗 经过查实,与删表之前的消耗资源是一样的
explain plan for select * from T3 ;
commit;
select * from table(dbms_xplan.display);
3.表碎片整理的步骤
进行表的碎片整理
alter table T3 enable row movement; --开启行移动执行shrink之前, 必须开启行移动
alter table T3 shrink space cascade; --收缩表
alter table T3 disable row movement; --关闭行移动
4.碎片整理后查看表的信息
(1)统计分析表的信息
BEGIN
dbms_stats.gather_table_stats(‘CDM’,‘T3’,CASCADE=>TRUE);
END;
analyze table T3 compute statistics;
(2)查看表使用的块大小
select blocks,empty_blocks,num_rows from user_tables where table_name=‘T3’;
– blocks 11
– empty_blocks 5
– num_rows 3000
(3)查看表使用的段大小
select sum(bytes)/1024/1024 from user_segments where segment_name=‘T3’; --0.125
select sum(bytes)/1024/1024 from user_segments where segment_name=‘IDX_T1_ID’ --0.125
(4)查看表水位线和占用空间
–高水位线明显变小了, 浪费空间也变小了
SELECT
TABLE_NAME,
(BLOCKS * 8192 / 1024 / 1024) “高水位空间MB”,
(NUM_ROWS * AVG_ROW_LEN / 1024 / 1024) “已用空间MB”,
blocks10/1008192/1024/1024 “预留空间MB(pctfree)”,
(BLOCKS * 8192 / 1024 / 1024)-(NUM_ROWS * AVG_ROW_LEN / 1024 / 1024)-(blocks10/1008192/1024/1024) “浪费空间MB”
FROM USER_TABLES
WHERE table_name = ‘T3’;
(5)查看执行计划的消耗:
查看消耗很少,同时可以看到,经过shrink 碎片整理,所以也没有丢失
explain plan for select * from T3 where id=1001 ;
commit;
select * from table(dbms_xplan.display);