说明
在我维护的 OLTP 系统中有一个接口中间表,其特点是只要本地系统的用户工单状态发生改变就会向中间表 INSERT
一条记录,而一但记录通过接口发送至集团公司就会 DELETE
。因此属于 DML 操作极为频繁。
影响
随着接口上线时间越来越长,对于这个中间表的 SELECT
操作出现在 AWR 报告的 Top-N 列表中
Gets CPU Elapsed
Buffer Gets Executions per Exec %Total Time (s) Time (s) SQL Id
-------------- ------------ ------------ ------ -------- --------- -------------
23,614,293 22,011 1,072.8 3.8 154.78 156.21 29kvjxhxapx9w
Module: JDBC Thin Client
select deal_code,deal_date,deal_user,deal_type,flow_inid,step_inco,deal_index,st
atus_value from deal_temp where (deal_type=0 or deal_type=2) order by insert_da
te
分析
DEAL_TEMP
是用来记录将要发至集团的工单办理情况记录,按照功能设计要求记录发送的速率要达到实时;因此这个中间表的记录数非常少,平均 < 10 条。
但遇到集团接口维护窗口,全国各省的接口程序都会要求关闭;这时本地工单办理情况记录就会一直存储在中间表中,表大小不断增大(有时记录数会超过 50万 条)。直到重启接口程序,记录数又会恢复到 10条 以下
查看当前 table segment 分配的大小
SQL> select bytes/1024/1024 from dba_segments where segment_name = 'DEAL_TEMP';
调整办法
因为我们使用的数据库版本为 10.2.0.4
所以可以使用 10g 的新特性 segment shrink
功能
SQL> alter table deal_temp enable row movement;
SQL> alter table deal_temp shrink space;