一、什么是水位线
所有的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. python-从文件中读取数据

    一.读取整个文件 learnFile.py 绝对路径 # coding=UTF-8 import sys reload(sys) with open(r'C:\Users\zhujiachun\Des ...

  2. MongoDB一次节点宕机引发的思考(源码剖析)

    目录 简介 日志分析 副本集 如何实现 Failover 心跳的实现 electionTimeout 定时器 业务影响评估 参考链接 声明:本文同步发表于 MongoDB 中文社区,传送门: http ...

  3. fenby C语言 P29

    野指针 malloc()分配内存: free()释放内存: p=(char*)malloc(100): #include <stdio.h>#include <stdlib.h> ...

  4. Docker安装方法整理

    目录 安装准备 在线安装 离线安装 Raspbian便捷脚本安装 卸载 安装准备: 卸载旧版本 较旧版本的Docker被称为docker或docker-engine.如果已安装,请卸载它们: sudo ...

  5. srync:@ERROR: auth failed on module tee 的解决办法分析

    首先:检查server端和client端的用户名和密码确认都无误: 然后:检查了服务器端/etc/rsyncd.conf 配置文件未发现异常, 再次:通过配置文件找到了log存放目录 $ cat /e ...

  6. Vue引入插件

    引入Element ui 1.在当前目录下,运行:npm i element-ui -S  2.在src/main.js中添加代码 import ElementUI from 'element-ui' ...

  7. Python项目生成所有依赖包的清单

    最近写完的自动化脚本,分享给同事的时候发现依赖包很难解决(使用的不是virtualenv环境).想起来之前看开源接口平台项目的时候可以一键下载依赖包,于是就找到了第三方包pipreqs,可以自动帮助我 ...

  8. 学习笔记_58 python语法基础

    1.python是解析型语言. 有点像javaScript在html运行一样,不需要mian函数入口,随时随地定义函数,执行函数, 执行语句,定义类型 2.python能面向对象 3.python使用 ...

  9. 学习笔记50_mongodb

    MongoVUE,MongoDB可视化客户端: 添加一个连接: 数据库下就是集合. 实际上是json数据的集合 Mongodb->数据库->文档集合:相当于表->文档:相当于表里面的 ...

  10. 使用Typescript重构axios(二十九)——添加baseURL

    0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...