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