读书笔记:Oracle临时表的重做日志机制解析
我们的文章会在微信公众号IT民工的龙马人生和博客网站( www.htz.pw )同步更新 ,欢迎关注收藏,也欢迎大家转载,但是请在文章开始地方标注文章出处,谢谢!
由于博客中有大量代码,通过页面浏览效果更佳。
本文为个人学习《Expert Oracle Database Architecture Techniques and Solutions for High Performance and Productivity(第四版本》一书过程中的笔记与理解分享,仅用于学习与交流,部分内容参考原书观点并结合>实际经验进行整理。若涉及版权问题,请联系删除或沟通处理。也请大家支持购买原版书籍。
Oracle临时表的重做日志机制解析
临时表的两种类型
Oracle数据库中有两种临时表,它们各有特点:
-
全局临时表:这是Oracle长期支持的功能,是存储在磁盘上的永久对象,所有会话都能看到。但表中的数据是临时的,只在事务或会话期间存在。
-
私有临时表(18c新增):仅存在于内存中,只对创建它的会话可见。可以设置为事务或会话结束时自动删除,更接近其他数据库(如SQL Server/MySQL)中的临时表概念。
临时表的重做日志特点
临时表最特别的地方在于它对重做日志(redo log)的处理方式。通过测试我们可以清楚地看到:
常规情况下的表现(未启用TEMP_UNDO_ENABLED)
-- 测试结果对比
永久表INSERT → 生成3,313,088字节redo
临时表INSERT → 仅生成72,584字节redo
永久表UPDATE → 生成3,268,384字节redo
临时表UPDATE → 生成1,946,432字节redo(约一半)
永久表DELETE → 生成3,245,112字节redo
临时表DELETE → 生成3,224,460字节redo(几乎相同)
规律总结:
- INSERT操作:临时表几乎不产生重做日志
- UPDATE操作:临时表产生的重做日志约为永久表的一半
- DELETE操作:两者产生的重做日志量相当
启用TEMP_UNDO_ENABLED后的变化
当设置ALTER SESSION SET TEMP_UNDO_ENABLED=TRUE
后,情况大变:
临时表INSERT → 仅376字节redo
临时表UPDATE → 仅376字节redo
临时表DELETE → 仅376字节redo
这个参数让临时表的DML操作几乎不再生成重做日志,对于大数据量操作能显著提升性能!
为什么会有这样的差异?
核心原因在于:
- 临时表只记录"撤销数据"(undo),不记录"重做数据"(redo)
- 启用TEMP_UNDO_ENABLED后,撤销数据改存到临时表空间,完全避开了重做日志
- 那376字节是Oracle内部管理开销,不可避免
实际应用建议
-
报表系统:临时表+Active Data Guard是绝配
- 将报表查询分流到备库
- 使用临时表存储中间结果
- 备库上临时表操作不产生任何重做日志!
-
批量处理:大事务操作临时表前,记得启用TEMP_UNDO_ENABLED
ALTER SESSION SET TEMP_UNDO_ENABLED=TRUE;
-
私有临时表:行为与全局临时表完全一致,选择依据是是否需要多会话共享
注意事项
- 默认情况下TEMP_UNDO_ENABLED=FALSE,需要手动开启
- Active Data Guard环境会自动启用临时表空间存储undo
- 那几百字节的redo是系统开销,不用担心
通过合理使用临时表和TEMP_UNDO_ENABLED参数,可以大幅减少数据库日志量,提升大批量数据操作的效率!
------------------作者介绍-----------------------
姓名:黄廷忠
现就职:Oracle中国高级服务团队
曾就职:OceanBase、云和恩墨、东方龙马等
电话、微信、QQ:18081072613
个人博客: (http://www.htz.pw)
CSDN地址: (https://blog.csdn.net/wwwhtzpw)
博客园地址: (https://www.cnblogs.com/www-htz-pw)