达梦数据库-学习-50-分区表指定分区清理空洞率(交换分区方式)

目录

一、环境信息

二、介绍

三、实验

1、测试数据生成

2、复制表创建

3、复制分区数据

4、数据量对比

5、复制表统计信息收集

6、查看空间占用

7、查看索引情况

8、查看统计信息

9、交换分区

10、数据对比

11、查看空间占用

12、查看索引情况

13、查看统计信息

14、删除复制表


一、环境信息

|------|------------------------------------------------------------------------------------------------------------------------------|
| 名称 | 值 |
| CPU | 12th Gen Intel(R) Core(TM) i7-12700H |
| 操作系统 | CentOS Linux release 7.9.2009 (Core) |
| 内存 | 4G |
| 逻辑核数 | 2 |
| DM版本 | 1 DM Database Server 64 V8 2 DB Version: 0x7000c 3 03134284194-20240703-234060-20108 4 Msg Version: 12 5 Gsu level(5) cnt: 0 |

二、介绍

最近在工作中出现分区表膨胀(空洞率高)的问题,一张分区表几个T的数据量,周末空窗期不一定能完成全表的空洞率清理,所以就想到了用交换分区的方式来做指定分区的空洞率清理,下面来分享一下步骤。

三、实验

生产中建议在空窗期内完成如下操作,操作期间建议原分区表没有增删改的操作。

1、测试数据生成

sql 复制代码
DROP TABLE IF EXISTS P_RANGE_DATE_TAB;
DROP TABLE IF EXISTS P_RANGE_DATE_TAB_COPY;

CREATE TABLE P_RANGE_DATE_TAB(C1 TIMESTAMP, C2 INT)
PARTITION BY RANGE(C1)( 
    PARTITION P2024   VALUES LESS THAN ('2025-01-01'), 
    PARTITION P2025   VALUES LESS THAN ('2026-01-01'), 
    PARTITION P2026   VALUES LESS THAN ('2027-01-01'),
    PARTITION PMax    VALUES LESS THAN (MAXVALUE) 
);
CREATE INDEX IDX_P_RANGE_DATE_TAB_SUN_1 ON P_RANGE_DATE_TAB(C1);
CREATE INDEX IDX_P_RANGE_DATE_TAB_SUN_2 ON P_RANGE_DATE_TAB(C2);

INSERT INTO P_RANGE_DATE_TAB VALUES ('2024-01-01',1); 
INSERT INTO P_RANGE_DATE_TAB VALUES ('2025-01-01',5); 
INSERT INTO P_RANGE_DATE_TAB VALUES ('2025-01-02',6); 
INSERT INTO P_RANGE_DATE_TAB VALUES ('2026-01-01',10); 
INSERT INTO P_RANGE_DATE_TAB VALUES ('2028-01-01',15); 
INSERT INTO P_RANGE_DATE_TAB SELECT '2025-01-01',LEVEL FROM DUAL CONNECT BY LEVEL <= 10000; 
INSERT INTO P_RANGE_DATE_TAB SELECT * FROM P_RANGE_DATE_TAB PARTITION(P2025);
INSERT INTO P_RANGE_DATE_TAB SELECT * FROM P_RANGE_DATE_TAB PARTITION(P2025);
COMMIT; 
BEGIN
	FOR I IN 1..18 LOOP 
        INSERT INTO P_RANGE_DATE_TAB SELECT * FROM P_RANGE_DATE_TAB;
        UPDATE P_RANGE_DATE_TAB SET C1 = date'2025-01-01' + 1 WHERE C1 = date'2025-01-01';
        DELETE FROM P_RANGE_DATE_TAB  WHERE C1 = date'2025-01-01' + 1;
        INSERT INTO P_RANGE_DATE_TAB SELECT date'2025-01-01',LEVEL FROM DUAL CONNECT BY LEVEL <= 1000; 
        COMMIT;
    END LOOP;
END;
/

2、复制表创建

sql 复制代码
CREATE TABLE P_RANGE_DATE_TAB_COPY(C1 TIMESTAMP, C2 INT); 
CREATE INDEX IDX_P_RANGE_DATE_TAB_COPY_SUN_1 ON P_RANGE_DATE_TAB_COPY(C1);
CREATE INDEX IDX_P_RANGE_DATE_TAB_COPY_SUN_2 ON P_RANGE_DATE_TAB_COPY(C2);

实际生产中,需要把表结构、索引等对象(除了分区信息)都建立上,不然交换分区时,会提示报错:[-7000]:交换对象不匹配。

按照实际情况创建结构,直接管理工具中点击表->属性,就可以获得完整结构,去掉分区即可。

3、复制分区数据

sql 复制代码
INSERT INTO P_RANGE_DATE_TAB_COPY SELECT * FROM P_RANGE_DATE_TAB PARTITION(P2025); 
COMMIT;

SQL按照实际情况修改,表名和分区名。

4、数据量对比

sql 复制代码
SQL> SELECT COUNT(*) FROM P_RANGE_DATE_TAB PARTITION(P2025);

行号     COUNT(*)            
---------- --------------------
1          1000

已用时间: 2.768(毫秒). 执行号:1162.

SQL> SELECT COUNT(*) FROM P_RANGE_DATE_TAB_COPY;

行号     COUNT(*)            
---------- --------------------
1          1000

已用时间: 9.616(毫秒). 执行号:1163.

对比一下数据量稳妥一些。

5、复制表统计信息收集

sql 复制代码
STAT 100 ON P_RANGE_DATE_TAB_COPY(C1);
STAT 100 ON P_RANGE_DATE_TAB_COPY(C2);

后续交换分区之后,统计信息也会变换过去。

6、查看空间占用

sql 复制代码
SELECT 
    OWNER,
    SEGMENT_NAME,
	PARTITION_NAME,
    SEGMENT_TYPE,
    ROUND(SUM(BYTES) / 1024, 2) AS TOTAL_SIZE
FROM DBA_SEGMENTS
WHERE 
OWNER = 'SYSDBA'
AND
SEGMENT_NAME IN ('P_RANGE_DATE_TAB','P_RANGE_DATE_TAB_COPY')
GROUP BY OWNER, SEGMENT_NAME, PARTITION_NAME, SEGMENT_TYPE
ORDER BY OWNER, SEGMENT_NAME, PARTITION_NAME, SEGMENT_TYPE;

行号     OWNER  SEGMENT_NAME          PARTITION_NAME SEGMENT_TYPE    TOTAL_SIZE
---------- ------ --------------------- -------------- --------------- ----------
1          SYSDBA P_RANGE_DATE_TAB      P2024          TABLE PARTITION 31488
2          SYSDBA P_RANGE_DATE_TAB      P2025          TABLE PARTITION 23680
3          SYSDBA P_RANGE_DATE_TAB      P2026          TABLE PARTITION 31488
4          SYSDBA P_RANGE_DATE_TAB      PMAX           TABLE PARTITION 31488
5          SYSDBA P_RANGE_DATE_TAB_COPY NULL           TABLE           256

已用时间: 138.117(毫秒). 执行号:1164.

P2025占用23680K

P_RANGE_DATE_TAB_COPY占用256K

7、查看索引情况

sql 复制代码
SELECT TABLE_OWNER,TABLE_NAME,TABLE_TYPE,STATUS,OWNER,INDEX_NAME,INDEX_TYPE FROM DBA_INDEXES
WHERE
TABLE_OWNER = 'SYSDBA'
AND
TABLE_NAME IN ('P_RANGE_DATE_TAB','P_RANGE_DATE_TAB_COPY')
ORDER BY TABLE_OWNER,TABLE_NAME;

行号     TABLE_OWNER TABLE_NAME            TABLE_TYPE STATUS OWNER  INDEX_NAME                      INDEX_TYPE
---------- ----------- --------------------- ---------- ------ ------ ------------------------------- ----------
1          SYSDBA      P_RANGE_DATE_TAB      TABLE      VALID  SYSDBA IDX_P_RANGE_DATE_TAB_SUN_2      NORMAL
2          SYSDBA      P_RANGE_DATE_TAB      TABLE      VALID  SYSDBA IDX_P_RANGE_DATE_TAB_SUN_1      NORMAL
3          SYSDBA      P_RANGE_DATE_TAB      TABLE      VALID  SYSDBA INDEX33555868                   CLUSTER
4          SYSDBA      P_RANGE_DATE_TAB_COPY TABLE      VALID  SYSDBA IDX_P_RANGE_DATE_TAB_COPY_SUN_1 NORMAL
5          SYSDBA      P_RANGE_DATE_TAB_COPY TABLE      VALID  SYSDBA INDEX33555883                   CLUSTER
6          SYSDBA      P_RANGE_DATE_TAB_COPY TABLE      VALID  SYSDBA IDX_P_RANGE_DATE_TAB_COPY_SUN_2 NORMAL

6 rows got

个数一半一半说明我们索引建全了,且都是有效的。

8、查看统计信息

sql 复制代码
SELECT OWNER,OBJECT_NAME,ID,COLID,T_FLAG,T_TOTAL,N_SAMPLE FROM SYSSTATS A
INNER JOIN
(    SELECT OBJECT_ID,OWNER,OBJECT_NAME FROM DBA_OBJECTS
        WHERE 
            OWNER = 'SYSDBA'
        AND
            OBJECT_NAME IN ('P_RANGE_DATE_TAB','P_RANGE_DATE_TAB_COPY')) B
ON A.ID = B.OBJECT_ID
ORDER BY OWNER,OBJECT_NAME,ID,COLID;

行号     OWNER  OBJECT_NAME           ID          COLID       T_FLAG T_TOTAL              N_SAMPLE            
---------- ------ --------------------- ----------- ----------- ------ -------------------- --------------------
1          SYSDBA P_RANGE_DATE_TAB_COPY 1193        0           C      1000                 1000
2          SYSDBA P_RANGE_DATE_TAB_COPY 1193        1           C      1000                 1000

已用时间: 3.047(毫秒). 执行号:1170.

我们可以看到复制表的统计信息。

原表我们没有收集,所以没有显示,是正常情况。

9、交换分区

sql 复制代码
ALTER TABLE P_RANGE_DATE_TAB EXCHANGE PARTITION P2025 WITH TABLE P_RANGE_DATE_TAB_COPY; 

按照实际情况改表名和分区名,别选错分区,导致分区数据错乱。

10、数据对比

sql 复制代码
SQL> SELECT COUNT(*) FROM P_RANGE_DATE_TAB PARTITION(P2025);

行号     COUNT(*)            
---------- --------------------
1          1000

已用时间: 7.302(毫秒). 执行号:1172.
SQL> SELECT COUNT(*) FROM P_RANGE_DATE_TAB_COPY;

行号     COUNT(*)            
---------- --------------------
1          1000

已用时间: 11.796(毫秒). 执行号:1173.

除了数据量的对比,数据内容也建议大致看一下,是否正确。

11、查看空间占用

sql 复制代码
SELECT 
    OWNER,
    SEGMENT_NAME,
	PARTITION_NAME,
    SEGMENT_TYPE,
    ROUND(SUM(BYTES) / 1024, 2) AS TOTAL_SIZE
FROM DBA_SEGMENTS
WHERE 
OWNER = 'SYSDBA'
AND
SEGMENT_NAME IN ('P_RANGE_DATE_TAB','P_RANGE_DATE_TAB_COPY')
GROUP BY OWNER, SEGMENT_NAME, PARTITION_NAME, SEGMENT_TYPE
ORDER BY OWNER, SEGMENT_NAME, PARTITION_NAME, SEGMENT_TYPE;

行号     OWNER  SEGMENT_NAME          PARTITION_NAME SEGMENT_TYPE    TOTAL_SIZE
---------- ------ --------------------- -------------- --------------- ----------
1          SYSDBA P_RANGE_DATE_TAB      P2024          TABLE PARTITION 31488
2          SYSDBA P_RANGE_DATE_TAB      P2025          TABLE PARTITION 1024
3          SYSDBA P_RANGE_DATE_TAB      P2026          TABLE PARTITION 31488
4          SYSDBA P_RANGE_DATE_TAB      PMAX           TABLE PARTITION 31488
5          SYSDBA P_RANGE_DATE_TAB_COPY NULL           TABLE           4352

已用时间: 100.927(毫秒). 执行号:1174.

|-----------------------|--------|-------|
| 名称 | 之前 | 如今 |
| P2025 | 23680K | 1024K |
| P_RANGE_DATE_TAB_COPY | 256K | 4252K |

P2025空间缩小为原有的23分之1,空间得到了清理。

12、查看索引情况

sql 复制代码
SELECT TABLE_OWNER,TABLE_NAME,TABLE_TYPE,STATUS,OWNER,INDEX_NAME,INDEX_TYPE FROM DBA_INDEXES
WHERE
TABLE_OWNER = 'SYSDBA'
AND
TABLE_NAME IN ('P_RANGE_DATE_TAB','P_RANGE_DATE_TAB_COPY')
ORDER BY TABLE_OWNER,TABLE_NAME;

行号     TABLE_OWNER TABLE_NAME            TABLE_TYPE STATUS OWNER  INDEX_NAME                      INDEX_TYPE
---------- ----------- --------------------- ---------- ------ ------ ------------------------------- ----------
1          SYSDBA      P_RANGE_DATE_TAB      TABLE      VALID  SYSDBA IDX_P_RANGE_DATE_TAB_SUN_2      NORMAL
2          SYSDBA      P_RANGE_DATE_TAB      TABLE      VALID  SYSDBA IDX_P_RANGE_DATE_TAB_SUN_1      NORMAL
3          SYSDBA      P_RANGE_DATE_TAB      TABLE      VALID  SYSDBA INDEX33555868                   CLUSTER
4          SYSDBA      P_RANGE_DATE_TAB_COPY TABLE      VALID  SYSDBA IDX_P_RANGE_DATE_TAB_COPY_SUN_1 NORMAL
5          SYSDBA      P_RANGE_DATE_TAB_COPY TABLE      VALID  SYSDBA INDEX33555870                   CLUSTER
6          SYSDBA      P_RANGE_DATE_TAB_COPY TABLE      VALID  SYSDBA IDX_P_RANGE_DATE_TAB_COPY_SUN_2 NORMAL

6 rows got

个数和之前一样,且都是有效的。

13、查看统计信息

sql 复制代码
SELECT OWNER,OBJECT_NAME,ID,COLID,T_FLAG,T_TOTAL,N_SAMPLE FROM SYSSTATS A
INNER JOIN
(    SELECT OBJECT_ID,OWNER,OBJECT_NAME FROM DBA_OBJECTS
        WHERE 
            OWNER = 'SYSDBA'
        AND
            OBJECT_NAME IN ('P_RANGE_DATE_TAB','P_RANGE_DATE_TAB_COPY')) B
ON A.ID = B.OBJECT_ID
ORDER BY OWNER,OBJECT_NAME,ID,COLID;

行号     OWNER  OBJECT_NAME      ID          COLID       T_FLAG T_TOTAL              N_SAMPLE            
---------- ------ ---------------- ----------- ----------- ------ -------------------- --------------------
1          SYSDBA P_RANGE_DATE_TAB 1190        0           C      1000                 1000
2          SYSDBA P_RANGE_DATE_TAB 1190        1           C      1000                 1000

我们可以看到原表的统计信息,说明统计信息也随着交换分区,转移过来了。

14、删除复制表

sql 复制代码
DROP TABLE IF EXISTS P_RANGE_DATE_TAB_COPY;

这一步建议在业务老师测试验证之后,再做删除操作。

相关推荐
Data_Journal2 小时前
【无标题】
大数据·服务器·前端·数据库·人工智能
qq_192779872 小时前
Python多线程与多进程:如何选择?(GIL全局解释器锁详解)
jvm·数据库·python
zbliquan2 小时前
SS928v100远程ubuntu交叉编译开发环境搭建
linux·运维·ubuntu
亚控科技2 小时前
超大型数据中心冷源群控升级:自主可控与智能调控的实践
数据库·智慧楼宇·kingscada·亚控科技·信创scada·大型数据中心
naruto_lnq2 小时前
NumPy入门:高性能科学计算的基础
jvm·数据库·python
我爱加班、、2 小时前
new Map()+Array.from()整理elementPlus的级联器数据
linux·前端·javascript
Apple_羊先森2 小时前
ORACLE数据库巡检SQL脚本--4、检查锁阻塞
数据库·sql·oracle
豆是浪个2 小时前
Linux(Centos 7.6)命令详解:top
linux·运维·服务器
2301_822365032 小时前
实战:用Python分析某电商销售数据
jvm·数据库·python