增删改undo生成量??index是否写undo?Oracle DML语句(insert,update,delete) ‘回滚开销估算‘

--insert操作 undo记录什么
--update操作 undo记录什么
--delete操作 undo记录什么

//index是否写undo?
结论是写。可通过对比加index之前和加index之后的undo生成量进行对比得出结论。

//undo数据产生量
redo中只会记录少量信息,这些信息足以重演事务;
undo中也只记录精简信息,这些信息足以撤消事务。

insert 产生undo最少,只记录插入记录的rowid;
update 中间,回滚段只需要记录被更新字段的旧值即可(前镜像),回退时通过旧值覆盖新值即可完成回退;
delete 最多,Oracle则必须记录整行的数据,在回退时,Oracle通过一个反向操作恢复删除的数据。
undo数据量查看:v$transaction.used_ublk


Oracle DML语句(insert,update,delete) '回滚开销估算'
一.--Oracle DML SQL回滚逻辑简介
数据库事务由1个或多个DML(insert,update,delete) SQL组成,Oracle数据库在进行DML操作需要使用UNDO表空间来保存事务回滚的信息,对于每种DML操作回滚的UNDO信息都不一样,大致如下:
//insert操作很简单,'只要保存记录插入到数据块及数据块内的槽号',回滚时只要根据数据块号及槽号做删除就可以了.
//update操作需要'保存记录位置',还需要'保存变更的字段原内容',回滚时采用原值即可.
//delete操作麻烦一些,不仅要'保存记录位置',还需要将'原有记录的内容全部保存下来',回滚时才能组成新的数据插入进去.

'如果表上有索引,则DML操作同时需要在UNDO表空间中保存索引相关的回滚信息'

--DML操作主要有以下几方面的开销构成:
//获取锁(CPU开销)
//定位要变更的记录(离散IO开销)
//记录回滚信息(CPU+IO开销)
//变更记录(CPU开销)
//记录重做日志(顺序IO开销)
//数据块写入(异步离散IO开销)

因为DML操作过程中记录回滚信息占用了非常大的一块资源,为了更好的估算DML操作需要回滚空间的大小,本文介绍了一些常用操作的估算方法及验证示例。


二.--如何查看事务UNDO使用空间
Oracle提供了系统视图v$transaction,里面保存了当前数据库活动事务的主要信息,可以用如下SQL来查看:

select b.sid,--会话编号
       b.serial#,
       b.username,
       b.machine,
       b.sql_hash_value,
       a.start_time,--事务启动时间
       a.used_ublk, --使用的undo块数
       a.used_urec, --使用的undo记录条数,是本文接下来的主要估算指标
       a.start_ubafil, --使用的undo文件号
       a.start_ubablk --使用的undo起始块号
  from v$transaction a,v$session b
 where a.ses_addr = b.saddr 
   and b.sid='XXXXXXX';
 
--由于测试环境就一个人使用,不存在并发,为简化操作,忽略会活参数,简化的SQL如下:
select used_urec from v$transaction;

--通过 start_ubafil 及 start_ubablk 可以dump回滚数据块的分析,如下所示:
alter system dump datafile start_ubafil block start_ubablk;

dump好后再通过日志文件分析数据块内的详细信息,也是通过这样的方法来确认计算公式,因为dump出来的内容比较复杂,是Oracle的具体实现细节,所以本文不介绍dump内容。


三.--测试准备
--创建表t1
SQL> create table t1 as select * from dba_objects;
Table created

SQL> select count(*) from t1;
  COUNT(*)
----------
     29495
     
SQL> desc t1;
Name           Type          Nullable Default Comments 
-------------- ------------- -------- ------- -------- 
OWNER          VARCHAR2(30)  Y                         
OBJECT_NAME    VARCHAR2(128) Y                         
SUBOBJECT_NAME VARCHAR2(30)  Y                         
OBJECT_ID      NUMBER        Y                         
DATA_OBJECT_ID NUMBER        Y                         
OBJECT_TYPE    VARCHAR2(18)  Y                         
CREATED        DATE          Y                         
LAST_DDL_TIME  DATE          Y                         
TIMESTAMP      VARCHAR2(19)  Y                         
STATUS         VARCHAR2(7)   Y                         
TEMPORARY      VARCHAR2(1)   Y                         
GENERATED      VARCHAR2(1)   Y                         
SECONDARY      VARCHAR2(1)   Y         
                
--object_id创建索引 
SQL> create index idx_t1_object_id on t1(object_id);
Index created

--object_name创建索引
SQL> create index idx_t1_object_name on t1(object_name);
Index created


四.--计算方法及测试脚本:USED_UREC
下面介绍事务中各种DML语句(insert,update,delete)使用undo记录的计算方法,每种操作会介绍估算公式并简单示例解释:

4.1.--delete 操作
4.1.2.--一般删除
//计算公式:USED_UREC=删除表记录数+删除表索引记录数(每个索引每行记录算一条记录)

假设表有2个索引,删除10条记录
--USED_UREC=10+2*10=30

SQL> delete from t1 where rownum<=10;
10 rows deleted

SQL> select USED_UREC from v$transaction;
 USED_UREC
----------
        30

SQL> commit;
Commit complete

4.1.2.--通过索引范围条件删除记录
//计算公式:USED_UREC=删除表记录数+更新索引块数

//假设表有1个单字段普通索引,通过索引范围查询10000条记录并删除,每个索引块大块保存200条记录
--USED_UREC=10000+10000/200=10050

SQL> delete from t1 where object_id between 10000 and 20000;
19871 rows deleted

SQL> select USED_UREC from v$transaction;
 USED_UREC
----------
     20242
     
SQL> commit;
Commit complete

4.2.--update 操作
4.2.1.--一般更新

//计算公式:USED_UREC=更新表记录数+更新索引记录变更数*2(每行索引变更有2个记录,一个是记录原索引指针,另外是记录新索引指针)
假设表有2个索引,更新10条记录的2个字段,其中要更新1个是普通字段,1个是索引字段
--USED_UREC=10+2*10=30

SQL> update t1 set object_name='TEST',owner='MK' where rownum<=10;
10 rows updated

SQL> select USED_UREC from v$transaction;
 USED_UREC
----------
        30
        
SQL> commit;
Commit complete

--注:
在语句中,普通字段不管更新前与更新后是否发生变化,都会产生UNDO记录,但是索引字段只有发生了变化才会产生UNDO记录,如下测试,object_name做了更新操作,但是没有发生变化,所以索引记录不会发生变更.

SQL> update t1 set object_name=object_name,owner='MK' where rownum<=10;
10 rows updated

SQL> select USED_UREC from v$transaction;
 USED_UREC
----------
        10
        
SQL> commit;
Commit complete

4.2.2.--通过索引范围条件更新该索引字段
//计算公式:USED_UREC=更新表记录数+更新索引块数*2
假设表有1个单字段普通索引,通过索引范围查询10000条记录并更新对应的索引字段,每个索引块大块保存200条记录
--USED_UREC=10000+2*(10000/200)=10100

SQL> update  t1 set object_id=object_id+1 where object_id>10000;
19584 rows updated

SQL> select USED_UREC from v$transaction;
 USED_UREC
----------
     19862
     
SQL> commit;
Commit complete

--注:
可以看出这种通过索引范围访问并更新该索引字段的情况非常少,要求也非常特殊.假设刚才的语句做一点小变化都不满足要求,如下加了一个rownum条件,实际更新的记录数都是一样的,但是使用的UNDO记录数只能按一般更新计算.

SQL> update t1 set object_id=object_id+1 where object_id>10000 and rownum<1000000;
19584 rows updated

SQL> select USED_UREC from v$transaction;
 USED_UREC
----------
     58752
     
SQL> commit;
Commit complete

4.3.--insert 操作
4.3.1.--单条insert (insert into t1 values …)
//计算公式:USED_UREC=新增记录数+表索引个数*新增记录数
假设表有2个索引,新增3条记录
--USED_UREC=3+3*2=9

SQL> insert into t1(owner,object_name,object_id) values('MK','test1',123456);
1 row inserted
SQL> insert into t1(owner,object_name,object_id) values('MK','test2',1234567);
1 row inserted
SQL> insert into t1(owner,object_name,object_id) values('MK','test3',12345678);
1 row inserted

SQL> select USED_UREC  from v$transaction;
 USED_UREC
----------
         9
         
SQL> commit;
Commit complete

4.3.2.--批量insert(insert into t1 select …)
这个非常难准确计算,因为新增记录会利用以前空闲的数据块,只有数据块有记录变化都需要保存数据块对应的回滚记录,同时也保存索引的回滚记录
//计算公式:--USED_UREC≈新增记录变更表数据块数+∑每个变更表数据块对应变更的索引块数

假设表有2个索引,新增1000条记录,每个数据块大约可保存600条记录,新增第一个数据块保存了600条记录,同时变更了第1个索引30个索引块,第2个索引40个数据块,新增第2个数据块保存了400条记录,同时变更了第1个索引20个索引块,第2个索引60个数据块
--USED_UREC≈2+(30+40+20+60)=152

SQL> insert into t1 select * from dba_objects where rownum<=10000;
10000 rows inserted

SQL> select USED_UREC  from v$transaction;
 USED_UREC
----------
      7837
      
SQL> commit;
Commit complete


五.--总结
1.以上脚本是在Oracle9.2上测试,Oracle对undo的处理非常复杂,这里介绍只是常用的一些dml产生undo估算方法;
2.从估算公式可以看出,索引对dml操作的影响非常大,当一个表有索引比没索引时做dml操作花费的undo开销非常具大,因为数据库要保证事务回滚的可行性,需要对索引做许多额外的事情,更新索引字段及批量insert操作尤其明显.
3.在有索引和没索引的表上做批量数据导入,性能有可能相关好几倍.通过估算oracle的dml操作需要的undo记录数,也可以间接估算一个dml还需要的时间.
4.工作中有时会遇到一个dml操作时间非常长,如果 v$session_longops 视图也没有可以跟踪的信息,这时就可以通过v$transaction的'used_urec'信息估算sql的进度.

dml在操作时,used_urec 是一直在增加的,当事务开始回滚时used_urec会开始下降,直到等于0,则回滚完成,因此也可以根据这个字段的变化判断回滚进度.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/598235.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python字典操作指南,掌握编程中必备的数据结构!

更多Python学习内容&#xff1a;ipengtao.com 字典&#xff08;Dictionary&#xff09;是Python中一种非常重要和常用的数据结构&#xff0c;它用于存储键-值对的数据。在Python中&#xff0c;字典是可变&#xff08;Mutable&#xff09;的、无序&#xff08;Unordered&#xf…

计算机视觉入门与调优

大家好啊&#xff0c;我是董董灿。 在 CSDN 上写文章写了有一段时间了&#xff0c;期间不少小伙伴私信我&#xff0c;咨询如何自学入门AI&#xff0c;或者咨询一些AI算法。 90%的问题我都回复了&#xff0c;但有时确实因为太忙&#xff0c;没顾得过来。 在这个过程中&#x…

Go调用jenkins api执行流水线构建与停止

用到的库&#xff1a; "github.com/bndr/gojenkins" 代码如下&#xff0c;一次到位&#xff1a; import ("context""fmt""time""github.com/bndr/gojenkins" )// 构建指定任务 func buildJob(ctx context.Context, jenkins…

Spark调优解析-sparkshuffle和程序开发优化2(七)

1Shuffle调优 1.1调优概述 大多数Spark作业的性能主要就是消耗在了shuffle环节&#xff0c;因为该环节包含了大量的磁盘IO、序列化、网络数据传输等操作。因此&#xff0c;如果要让作业的性能更上一层楼&#xff0c;就有必要对shuffle过程进行调优。但是也必须提醒大家的是&a…

勒索事件急剧增长,亚信安全发布《勒索家族和勒索事件监控报告》

近期(12.15-12.21)态势快速感知 近期全球共发生了247起攻击和勒索事件&#xff0c;勒索事件数量急剧增长。 近期需要重点关注的除了仍然流行的勒索家族lockbit3以外&#xff0c;还有本周top1勒索组织toufan。toufan是一个新兴勒索组织&#xff0c;本周共发起了108起勒索攻击&a…

Springboot和Spring有什么区别

SpringBoot和Spring的关系 不是&#xff1a;从马车到汽车那种交通出行的颠覆&#xff0c;从燃油车到纯电动车那种能源利用的变革&#xff0c;从人工驾驶到AI智能那种驾驶方式的升级。总之&#xff0c;不是产品的升级换代&#xff0c;不是谁要替换谁。而是&#xff1a;汽车从手…

基于数据库和NER构建知识图谱流程记录

文章目录 环境准备拓扑设计构建流程设计文件流设计交互解析算法实现数据库交互NER解析相似度计算 基于数据库的文件生成从数据库中读取字段将字段后处理后保存为文件 基于文件的知识图谱构建bug修改与算法优化图数据库连接问题批量构建知识图谱问题批量删除边问题空值处理问题去…

集成开发环境(IDE)的用途?

集成开发环境&#xff08;IDE&#xff09;是一种用于提供程序开发环境的应用程序&#xff0c;它集成了代码编写功能、分析功能、编译功能、调试功能等一体化的开发软件服务套。以下是IDE的一些主要用途&#xff1a; 1.提供代码编写功能&#xff1a;IDE可以提供代码编辑器&…

pygame学习(二)——绘制线条、圆、矩形等图案

导语 pygame是一个跨平台Python库(pygame news)&#xff0c;专门用来开发游戏。pygame主要为开发、设计2D电子游戏而生&#xff0c;提供图像模块&#xff08;image&#xff09;、声音模块&#xff08;mixer&#xff09;、输入/输出&#xff08;鼠标、键盘、显示屏&#xff09;模…

商城小程序(5.商品列表)

目录 一、定义请求参数对象二、获取商品列表数据三、渲染商品列表结构四、把商品item封装为自定义组件五、使用过滤器处理价格六、上拉加载更多七、下拉刷新八、点击商品item项跳转到详情页面 这章主要完成商品列表页面的编写&#xff1a;位于subpkg分包下的goods_list页面 一…

Python常用代码大全

1、Hello World 1 print("Hello World!") 这段代码使用 print 函数输出字符串 “Hello World!” 到控制台。 2、计算数字的平方和 以下是使用 python 计算数字的平方和的代码&#xff1a; 1 2 3 4 5 6 7 def square_sum(numbers): sum 0 for num in n…

【竞技宝】DOTA2:二号位地位发生变化 圣斧、血棘助法核重回巅峰!

北京时间2024年1月5日&#xff0c;目前国服已经更新7.35b版本一段时间了&#xff0c;在这段时间里&#xff0c;各位看官是否感受到了比赛节奏和英雄胜率方面的变化呢&#xff1f;从全分段的出场率以及胜率的变化来看&#xff0c;二号位在游戏内的地位已经发生了很大的变化。 在…

DrGraph原理示教 - OpenCV 4 功能 - 膨胀腐蚀

在二值图的结果基础上&#xff0c;可针对性处理。 这些处理有些是概念上的&#xff0c;有些是原理上的&#xff0c;也有形态上的&#xff0c;那就看用途与目的了。 本质上还是对二值图的黑白点进行处理&#xff0c;以用于图像增强、边缘检测、图像分割等多个领域。比如膨胀与腐…

Capsolver:解决Web爬虫中CAPTCHA挑战的最优解决方案

Web爬虫已经成为从各种在线来源提取和分析数据的不可或缺的技术。然而&#xff0c;在Web爬取过程中&#xff0c;经常会遇到的一个共同挑战是CAPTCHA。CAPTCHA&#xff08;完全自动化的公共图灵测试&#xff0c;用于区分计算机和人类&#xff09;是一种安全措施&#xff0c;旨在…

vue3中使用elementplus中的el-tree-select,自定义显示名称label

<el-tree-select v-model"addPval" node-key"id" :data"menulists" :render-after-expand"false" :props"menuProps" /> <el-divider />let menuProps {//自定义labellabel: (data: { name: any; }) > {ret…

Asp .Net Core系列:基于MySQL的DBHelper帮助类和SQL Server的DBHelper帮助类

文章目录 MySQLDBHelperMSSQLDBHelper MySQLDBHelper app.config中添加配置 <connectionStrings><add name"MySqlConn" connectionString"serverlocalhost;port3306;userroot;password123456;databasedb1;SslModenone"/></connectionStrin…

web期末个人引导页透明版

效果图 代码 css代码 * {box-sizing: border-box; }body {color: #2b2c48;font-family: "Jost", sans-serif;background-image: url(../img/bg.jpg);background-repeat: no-repeat;background-size: cover;background-position: center;background-attachment: fix…

杨中科 ASP.NETCore开发效率利器 HOT RELOAD

HOT RELOAD 1、困惑:修改了服务器端的代码&#xff0c;必须重新运行程序。 2、方法1: [启动 (不调试) ] 3、方法2: .NET 6开始的Hot Reload(热重载) 正常修改代码后 不重启&#xff0c;是无法看到新的数据展示在页面 修改 运行结果&#xff1a; 方式一&#xff1a;设置开始…

java+vue+uniapp开发的前后端分离社交论坛问答发帖

源码介绍&#xff1a; 前后端分离社交论坛问答发帖BBS源码&#xff0c;社交论坛小程序|H5论坛| app论坛是javavueuniapp开发的前后端分离社交论坛问答发帖/BBS项目&#xff0c; 包括论坛图文帖&#xff0c;视频&#xff0c;圈子&#xff0c;IM私聊&#xff0c;微信支付&…

PyTorch数据并行(DP/DDP)浅析

一直以来都是用的单机单卡训练模型&#xff0c;虽然很多情况下已经足够了&#xff0c;但总有一些情况得上分布式训练&#xff1a; 模型大到一张卡放不下&#xff1b;单张卡batch size不敢设太大&#xff0c;训练速度慢&#xff1b;当你有好几张卡&#xff0c;不想浪费&#xf…