Oracle 高低水位线的学习


背景

最近产品的一些脚本会大量的给一些流程表里面插入数据
因为只是一个流程相关没有时序查询的需求
所以数据量挺大, 但是按照石时间戳删除非常麻烦. 
自己执行过多次delete 但是使用自己的SQL查询表大小,发现总是失败
想起来可能跟高低水位线有关系, 所以这里学习了解一下. 

我理解水位线不进行处理, 在进行全表扫描时 ,会多扫描很多无效的区块
对性能是一个伤害, 所以应该努力降低一下相应的水位线. 

Oracle为了性能 并不会将所有的表放到一个特定的增长位置
所以就会出现, 数据库数据文件增长上去之后没有办法再缩小回来. 

SQLSERVER 没有这样的问题, 但是性能会差一下

为了解决这样的问题 exp/expdp 的备份恢复方式其实是会修改高低水位线的

再不是非常大的 并且有停机时间的环境下面执行一下备份恢复 重建表的查询统计信息对性能其实很有帮助.

查询情况

表空间名称

表空间大小(M)

表空间剩余大小(M)

表空间使用大小(M)

表空间大小(G)

表空间剩余大小(G)

表空间使用大小(G)

使用率 %

SYSTEM

920

105.625

814.375

0.8984375

0.1031494140625

0.7952880859375

88.52

xxxxORA

1925120

545808.5625

1379311.4375

1880

533.01617431640625

1346.98382568359375

71.65

UNDOTBS2

32024

31099.9375

924.0625

31.2734375

30.37103271484375

0.90240478515625

2.89

SYSAUX

7525

423.3125

7101.6875

7.3486328125

0.41339111328125

6.93524169921875

94.37

USERS

5

4

1

0.0048828125

0.00390625

0.0009765625

20


使用的SQL

SELECT
	a.tablespace_name "表空间名称",
	total / ( 1024 * 1024 ) "表空间大小(M)",
	free / ( 1024 * 1024 ) "表空间剩余大小(M)",
	( total - free ) / ( 1024 * 1024 ) "表空间使用大小(M)",
	total / ( 1024 * 1024 * 1024 ) "表空间大小(G)",
	free / ( 1024 * 1024 * 1024 ) "表空间剩余大小(G)",
	( total - free ) / ( 1024 * 1024 * 1024 ) "表空间使用大小(G)",
	round( ( total - free ) / total, 4 ) * 100 "使用率 %" 
FROM
	( SELECT tablespace_name, SUM( bytes ) free FROM dba_free_space GROUP BY tablespace_name ) a,
	( SELECT tablespace_name, SUM( bytes ) total FROM dba_data_files GROUP BY tablespace_name ) b 
WHERE
	a.tablespace_name = b.tablespace_name

修改表的水位线-尝试1

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

发现这个SQL根本无效

修改表的水位线-尝试2

truncate 表可以直接降低水位线

所以想法是 先按照时间戳字段删除大部分数据
然后create tableback as select * from tablesource 建立备份表

然后truncate table tablesource 的方式处理表
然后 insert into tablesource select * from tableback

发现这样处理之后 数据库 查询出来的表大小就会发生变化了.

部分表信息

TABLE_NAMEINFO

TABLE_ROWNUM

TABLE_COLNUM

TABLE_SIZE

table1_name

2097322

569

76672.875

table2_name

62184

216

27706.5

复制表之后

TABLE_NAMEINFO

TABLE_ROWNUM

TABLE_COLNUM

TABLE_SIZE

table1_name_BACK

744443

68

6696.6875


修改一下表大小获取的SQL

SELECT
    x.table_name AS table_nameinfo,
    x.表行数 AS table_rownum,
    x.表列数 AS table_colnum,
    y.表大小 AS table_size ,
    x.table_tablespace as table_tablespace
FROM
    (
    SELECT
        b.table_name,
        a.num_rows AS 表行数,
        b.count1 AS 表列数 ,
                                a.TABLESPACE_name as table_tablespace
    FROM
        user_tables a
        INNER JOIN ( SELECT table_name, count( column_name ) AS count1 FROM user_tab_columns GROUP BY table_name ) b ON a.table_name = b.table_name
    ORDER BY
        b.table_name
    ) x LEFT outer
    JOIN (
    SELECT
        sum( tablesize ) AS 表大小,
        tablename
    FROM
        (
        SELECT
            sum( C.bytes ) / 1024 / 1024 AS tablesize,
            C.table_name AS tablename
        FROM
            ( SELECT A.table_name, B.bytes FROM USER_lobs A, USER_extents B WHERE A.segment_name = B.segment_name ) C
        GROUP BY
            C.table_name UNION ALL
        SELECT
            sum( bytes ) / 1024 / 1024 AS tablesize,
            segment_name AS tablename
        FROM
            user_extents
        WHERE
            segment_type = 'TABLE'
        GROUP BY
            segment_name
        )
    GROUP BY
        tablename
    ORDER BY
        1 DESC
    ) y ON x.table_name = y.tablename
ORDER BY
    nvl(y.表大小,0) desc FETCH NEXT 100 ROWS ONLY