一、什么是水位线
所有的oracle段都会有一个在段内容纳数据的上线,把这个上限成为“high water mark”,这是一个标记,用来说明已经有多少没有使用的数据块分配给这个段,原则上high water mark只会增大,不会减小,即使delete将表中的数据全部删除,high water mark还是原值,这就使得high water mark就像水库的历史最高水位,但是如果使用truncate,该表的high water mark就会被重置成0.
 
二、数据库操作的影响
1)全表扫描通常要读出HWM标记的所有属于该表的数据库快,即使该表没有任何数据
2)即使HWM以下有空闲的数据库块,在插入时使用的是HWM以上的数据块,此时HWM会自动增大
 
三、如何知道一个表的HWM?
1)首先对表进行分析
ANALYZE TABLE <TABLENAME> ESTIMATE/COMPUTE STATISTICS
2)SELECT BLOCKS,EMPTY_BLOCKS,NUM_ROWS
    FROM USER_TABLES
   WHERE TABLE_NAME = <TABLENAME>
SELECT BLOCKS,--水位线
       EMPTY_BLOCKS,--从来没有使用过的数据块
       NUM_ROWS
  FROM USER_TABLES
WHERE TABLE_NAME = 'TP_WLJR0005'
 备注:blocks列代表该表中曾经使用过的数据库块的数目,即水位线
       empty_blocks代表分配给该表,但是在水位线以上的数据库块,即从来没有使用过的数据块
 
三、oracle表段中的高水位线HWM
在oracle的存储中,高水位线在日常的增删改查中只会上涨,不会下降
1.先得明白select的查询特性:select查询时候,会对表中数据进行一次扫描,并不是说数据块有多少数据就扫描多少数据,其决定因素:高水位线以下的数据。
    例:新建A表,这时高水位线是0,所以这时查询速度就极快,然后A表插入1000万条数据,这时高水位已经提到了1000W的级别,再次查询的时候,对表中数据扫描就会按照实时的高水位线以下进行扫描。如果delete把数据全部删除,但是高水位线依旧在1000W的级别,查询时候仍然会按照1000W的高水位线进行扫描。
    这就是为什么有时候表中数据很少,但是查询速度很慢,其原因就是因为该表的高水位线决定的。
2.降低高水位线:使用truncate语句进行删除表中数据,相当于重新新建了表,不仅把数据清空,而且把高水位线拉低至0。
    适用于数据量大的临时表
 
四、修正oracle的高水位线
在oracle中,执行delete操作并不会降低高水位线,导致查询性能降低。
降低高水位线的操作
 
1.执行表重建指令 alter table table_name move;
在线转移表空间ALTER TABLE ...MOVE TABLESPACE...,其中MOVE后面不跟着参数也可以,默认还是原来表空间,MOVE后记住重建索引。
如果以后还要继续向这个表增加数据,没有必要MOVE,只是释放出来的空间只能这个表用,其他的表或者segment无法使用该空间
2.执行alter table table_name shrink space.压缩碎片,回收高水位线。
注意:此命令为Oracle 10g新增功能,再执行该命令之前必须允许alter table table_name enable row monement;
3.赋值要保留的数据到临时表,drop原表,然后rename临时表为原表名。
4.alter table table_name deallocate unused
5.truncate
 
 
开发环境试验
选择降低高水位线的方式:shrink space
原因:move确实整理碎片的效率很高,但是不移动高水位线,而且还要重建索引;shrink space整理碎片不仅能降低高水位线,而且不需要重新建索引,但是使用shrink space之前一定要进行行迁移
move不能移动高水位线的原因:alter table move不能修改rowid,且shrink space能修改rowid,但是要先进行行迁移
 
1.先把碎片率高的表找出来
select 'drop table ' || segment_name || ' purge;',
       sum(bytes) / 1024 / 1024 Mbytese
  from user_segments a, user_tables b
where segment_type = 'TABLE'
   and a.segment_name = b.TABLE_NAME
   and b.COMPRESSION = 'DISABLED'
group by segment_name, COMPRESSION
order by sum(bytes) / 1024 / 1024 desc;
 
SELECT table_name,
       ROUND((blocks * 8/1024), 2) "高水位空间 M",
       ROUND((num_rows * avg_row_len / 1024/1024), 2)  "真实使用空间 M",
       ROUND((blocks * 10 / 100) * 8, 2) "预留空间(pctfree)  M",
       ROUND((blocks * 8 - (num_rows * avg_row_len / 1024)  -blocks * 8 * 10 / 100), 2) "浪费空间 M",
       ((blocks * 8-(num_rows * avg_row_len /  1024))/1024)/(blocks * 8/1024) "浪费空间 %"
  FROM user_tables
WHERE table_name = 'TP_WLJR0005';
在高水位和真实使用空间之间的差距=浪费空间,产生浪费空间的原因是高水位线的上涨,真实使用空间变小(大量的delete造成的),当浪费空间%达到25%就需要整理了。
 
2.开启行迁移
行迁移补充:在ORACLE中,当执行一条UPDATE 语句时候,可能会使一行的长度增加,从而其实不能放在一个数据块,这是Oracle就会自动寻找一个能容纳下该行的数据块,如果能找到,那么Oracle会把该行的数据全部搬到新的数据块中,只留下一个指针(Point)指向新的块,但是行标识(rowid)没有变化,依旧是之前的数据块。当访问这条记录时候,Oracle先会找到原来的数据块,然后通过指针指向新的数据块。
alter table TP_WLJR0005 enable row movement;--开启行迁移
 
3.碎片压缩
alter table table_name shrink space cascade;--进行压缩
 
4.关闭行迁移
alter table table_name disable row movement;--关闭行迁移
 
脚本:

--查看该用户下表段空间情况
select 'drop table ' || segment_name || ' purge;',
sum(bytes) / 1024 / 1024 Mbytese
from user_segments a, user_tables b
where segment_type = 'TABLE'
and a.segment_name = b.TABLE_NAME
and b.COMPRESSION = 'DISABLED'
group by segment_name, COMPRESSION
order by sum(bytes) / 1024 / 1024 desc;
--查看某个表的高水位线情况
SELECT table_name,
ROUND((blocks * 8/1024), 2) "高水位空间 M",
ROUND((num_rows * avg_row_len / 1024/1024), 2) "真实使用空间 M",
ROUND((blocks * 10 / 100) * 8, 2) "预留空间(pctfree) M",
ROUND((blocks * 8 - (num_rows * avg_row_len / 1024) -blocks * 8 * 10 / 100), 2) "浪费空间 M",
((blocks * 8-(num_rows * avg_row_len / 1024))/1024)/(blocks * 8/1024) "浪费空间 %"
FROM user_tables
WHERE table_name = 'TP_WLJR0005';
--开启行迁移
alter table tp_wljr0005 enable row movement;
--压缩碎片
ALTER TABLE TP_WLJR0005 SHRINK SPACE CASCADE;
--查看表段空间
select sum(bytes)/1024/1024 from user_segments where segment_name='TP_WLJR0005';
--收集统计信息
exec dbms_stats.gather_table_stats('TPS','TP_WLJR0005',CASCADE=>TRUE); --在toad里面执行
--关闭行迁移
alter table tp_wljr0005 disable row movement;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Oracle的高水位线的更多相关文章

  1. Oracle释放高水位线

    /*****************************************************************原因:由于原导出数据库没有整理表空间其中主要包括两方面,一是用户产生 ...

  2. Oracle数据库入门——高水位线详解

    一.什么是水线(High Water Mark)? 所有的oracle段(segments,在此,为了理解方便,建议把segment作为表的一个同义词) 都有一个在段内容纳数据的上限,我们把这个上限称 ...

  3. oracle 高水位线详解

    一.什么是水线(High Water Mark)? 所有的oracle段(segments,在此,为了理解方便,建议把segment作为表的一个同义词) 都有一个在段内容纳数据的上限,我们把这个上限称 ...

  4. 一、oracle 高水位线详解

    一.什么是水线(High Water Mark)? 所有的oracle段(segments,在此,为了理解方便,建议把segment作为表的一个同义词) 都有一个在段内容纳数据的上限,我们把这个上限称 ...

  5. oracle 高水位线

    一.oracle 高水位线详解 一.什么是水线(High Water Mark)? 概念: 1.块: 是粒度最小的存储单位,现在标准的块大小是8K,ORACLE每一次I/O操作也是按块来操作的,也就是 ...

  6. Oracle 高水位线和全表扫描

    --Oracle 高水位线和全表扫描--------------------------2013/11/22 高水位线好比水库中储水的水位线,用于描述数据库中段的扩展方式.高水位线对全表扫描方式有着至 ...

  7. [转载]oracle 高水位线详解

    一.oracle 高水位线详解 出处: https://www.cnblogs.com/linjiqin/archive/2012/01/15/2323030.html 一.什么是水线(High Wa ...

  8. 08 Oracle表碎片查询以及整理(高水位线)

    Oracle表碎片查询以及整理(高水位线) 1.表碎片的来源 当针对一个表的删除操作很多时,表会产生大量碎片.删除操作释放的空间不会被插入操作立即重用,甚至永远也不会被重用. 2.怎样确定是否有表碎片 ...

  9. oracle 基础知识(十五)----高水位线

    一,oracle的逻辑存储管理 ORACLE的逻辑存储管理,分4个粒度:表空间,段,区和块. ## 块 粒度最小的存储单位,现在标准的块大小是8K,ORACLE每一次I/O操作也是按块来操作的,也就是 ...

随机推荐

  1. 实用脚本awk

    非常实用的awk 有时候需要去服务器下载几个日志 日志太多,翻滚起来很麻烦,操作又慢又复杂. 可以使用这个下载最新的两个文件 ls -lt | head -3 | awk -F ' ' '{if(NR ...

  2. Spring(四)Spring与数据库编程

    Spring最重要的功能毫无疑问就是操作数据.数据库的百年城是互联网编程的基础,Spring为开发者提供了JDBC模板模式,那就是它自身的JdbcTemplate.Spring还提供了Transact ...

  3. 构建企业级数据湖?Azure Data Lake Storage Gen2实战体验(下)

    相较传统的重量级OLAP数据仓库,“数据湖”以其数据体量大.综合成本低.支持非结构化数据.查询灵活多变等特点,受到越来越多企业的青睐,逐渐成为了现代数据平台的核心和架构范式. 作为微软Azure上最新 ...

  4. apply 、 call 、 bind的用法

    1.apply 方法 apply:调用一个对象的一个方法,用另一个对象替换当前对象.例如:B.apply(A, arguments);即A对象应用B对象的方法. apply方法最多只能有两个参数——新 ...

  5. SVM详细笔记及总结

    本文精品,如有疑问欢迎留言or微信咨询:523331232

  6. cacti1.2.7安装教程+Centos7|Cacti1.2.x+Centos7+Spine1.2.7零基础手把手教学

    cacti1.2.7安装教程+Centos7|Cacti1.2.x+Centos7+Spine1.2.7零基础手把手教学 教程地址: 链接:http://note.youdao.com/notesha ...

  7. 【MySQL】MySQL数据类型

    MySQL表数据存储大小说明 MySQL中规定,任何一条记录(数据表中每行数据)理论上的最大存储容量为 2^16 - 1 (Bytes) = 65535字节. MySQL数据类型思维导图 MySQL数 ...

  8. Java 数据类型和初始值

    Java 基本数据类型 byte.short.int.long.float.double.boolean.char byte 数据类型是8位.有符号的,以二进制补码表示的整数 short 数据类型是 ...

  9. TypeError: expected string or bytes-like object

    在写Python代码的时候,遇到了"TypeError: a bytes-like object is required, not 'str'"错误,此处实验机器的Python环境 ...

  10. C语言I博客作业04

    这个作业属于那个课程 C语言程序设计II 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/SE2019-1/homework/9773 我在这个课程的目标 ...