Oracle的高水位线
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Oracle的高水位线,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5446字,纯文字阅读大概需要8分钟。
内容图文
![Oracle的高水位线](/upload/InfoBanner/zyjiaocheng/882/1f491af87d4d49ce909f8efe4b7ba92c.jpg)
一、什么是水位线
所有的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的高水位线全部内容,希望文章能够帮你解决Oracle的高水位线所遇到的程序开发问题。
如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
来源:【匿名】