表级别碎片过多原因
表再频繁经历delete,insert 后,容易产生大量碎片空间。ORACLE有Delayed block cleanout特性,即对表进行DML操作之后,Oracle只会标记相应的数据块为修改状态,当表上记录被Delete,空间可能并没有被真正释放,接着进行Insert操作时,Oracle将把新记录插入到新的extent之中没有利旧,从而导致表产生大量碎片,对数据库性能产生较大影响。
故障模拟
测试环境通过以下脚本,初始化一张表SYST1,插入数据约2300W。
查看空间大小,该表占用了约2.5G的空间:
模拟碎片情况,删除绝大部分数据。
查询全表数据(未建索引走了全表,未收集统计信息有动态采样),非常慢。2560条数据,约40秒。
故障分析
执行计划中 可以看到,全表扫描物理读很高,其实扫描了很多空块(没有收集统计信息,这里看不到具体块数的情况)。
处理思路
处理上有多种方式:CTAS,导入导出,在线重定义等,数据库版本10.2.0.5及以上版本,相对推荐shrink的方式。如下:
处理后收益明显,sql秒出。
巡检思路
表碎片的巡检分析依赖表上的统计信息,在没有统计信息或是统计信息过旧的情况下,无法巡检到有碎片的表。所以保障表上有统计信息的情况下,检查表上碎片率,对碎片率过高,表较大的TOP N 给予提示。
隐患分析
表碎片不仅浪费空间,还严重影响数据库性能,示例中较为极端,调整后效果也更明显。实际生产当中碎片率达到90%以上的场景也很常见,为保障数据库处于良好的运行状态,建议定期对频繁访问的表做碎片分析并清理碎片。
领取专属 10元无门槛券
私享最新 技术干货