最近,bi同事的反馈指出了一张表的数据查询速度非常慢,尽管该表的数据总量不足1万行。我们首先考虑的是高水位线(hwm)带来的性能问题,即高水位线下占用了大量数据块,而这些数据块中大部分是空闲的。
我们知道,在全表扫描时,高水位线下的所有数据块都会被扫描,因此扫描的数据块数量可能远远超过实际存储数据的数据块数量。
一、收集表的统计信息
要获取准确的高水位信息,首先需要收集统计信息,这样得到的信息才会相对准确。
ANALYZE TABLE table_name ESTIMATE STATISTICS;ANALYZE TABLE table_name COMPUTE STATISTICS FOR TABLE FOR ALL INDEXES FOR ALL INDEXED COLUMNS;execute dbms_stats.gather_table_stats(ownname => 'OWNER', tabname => 'TABLE_NAME', estimate_percent => null, method_opt => 'for all indexed columns', cascade => true);
二、查看表信息
查看表的块和行信息:
select t.TABLE_NAME, t.NUM_ROWS, t.BLOCKS, t.empty_blocks, t.LAST_ANALYZED from dba_tables t where table_name in ('TABLE_NAME');SELECT COUNT(DISTINCT DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)) USED_BLOCK FROM TABLE_NAME;

上述查询结果显示,当前表的行数为9651行,HWM下的数据块使用了716119个,而未使用的数据块为0个。
实际数据占用的数据块数量为152个。
从中可以看出,高水位线下有716119-152个数据块可以释放,这样每次全表扫描只需扫描152个数据块即可。
通过查看段大小来验证记录数和表大小是否一致,段大小为5.5G,9651行的记录几乎不可能达到这个大小,因此可以断定其中有很多空闲块。
select segment_name, bytes/1024/1024/1024 TSize_GB from dba_segments where segment_name='table_name' ---5876219904

三、问题原因
ViiTor实时翻译
AI实时多语言翻译专家!强大的语音识别、AR翻译功能。
116 查看详情
什么情况下会导致上述问题,即高水位线下存在大量未使用的数据块?通常是大表(插入大量记录后)经过批量删除操作(delete),未释放高水位线所致。
全表扫描需要读取高水位线下的所有数据块,无论是否包含数据。如果在插入数据时使用了append关键字,即使高水位线下有空闲的数据块,也会从高水位线上方的数据块进行分配,导致高水位线上升。
四、降低高水位的方法
alter table table_name move; 此方法可以释放高水位,但需要重建索引。alter table table_name shrink space; 此方法可以释放高水位,但在执行前需要启用行移动:alter table table_name enable row movement;使用导出/导入(exp/imp)方式重建表数据。使用删除/创建(drop/create)方式重建表。使用truncate表。alter table table_name deallocate unused; 此方法用于释放HWM上方的未使用空间,但不会释放HWM下方的自由空间,也不会移动HWM的位置。
五、高水位调整实施
统计信息收集(如上所述)。查看执行计划:
SQL> set autotrace trace;SQL> set timing on;SQL> SELECT count(*) FROM TABLE_NAME;

表移动:
alter table table_name move;
报错:ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired查看被锁对象:
select object_name, machine, s.sid, s.serial# from v$locked_object l, dba_objects o, v$session s where l.object_id=o.object_id and l.session_id=s.sid;
执行后再查看执行计划统计信息:

可以看到,统计信息中访问的数据块已经减少,全表扫描速度也大大提升。
索引重建:
alter index index_name rebuild online;
六、库高水位对象统计
①比较表的行数和表的大小关系。如果行数为0,而表的当前占用大小减去初始化时的大小(INITIAL_EXTENT)后依然很大,说明该表有高水位。
②行数和块数的比率,即查看一个块可以存储多少行数据。如果一个块存储的行数少于5行甚至更少,说明有高水位。注意,这两种方法都不是十分准确,需要对查询结果进行进一步筛选。在查询表的高水位时,首先需要分析表,以获取最准确的统计信息。
SELECT D.OWNER, ROUND(D.NUM_ROWS / D.BLOCKS, 2), D.NUM_ROWS, D.BLOCKS, D.TABLE_NAME, ROUND((d.BLOCKS*8-D.INITIAL_EXTENT/1024)/1024) t_size FROM DBA_TABLES D WHERE D.BLOCKS > 10 AND ROUND(D.NUM_ROWS / D.BLOCKS, 2) 50 AND OWNER NOT LIKE '%SYS%' AND BLOCKS > 100 ORDER BY WASTE_PER DESC;
以上就是Oracle实例之HWM(高水位线)性能优化的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/457434.html
微信扫一扫
支付宝扫一扫