注册
奇怪的 DELETE 慢优化

奇怪的 DELETE 慢优化

Grrr 2021/11/15 2852 17 0
摘要 记录一次 DELETE 慢优化

近期接北京同事的请求对某测试项目进行了优化,大致场景如下:

按 id 去删 100w 的表,可以确认字段类型和绑定参数类型是匹配的,都是 varchar,能走二级索引,并发 20,每条要 2、3s。

检查 TOP/PERF ,发现 SYS CPU 不高,PERF 无明显热点,但是有少量 CSCN 操作符痕迹。
根据现场人员反馈,测试过程中在 MANAGER 客户端执行 DELETE 语句并不慢,大概 20ms。

检查 PURGE 线程,发现 PURGE ITEM 不多,PURGE 线程也不处于活跃状态,现场并行 PURGE 已经开启。

检查 UNDO EXTENT NUM,发现是默认值 4,我们修改为 128。

修改后再次进行测试,并没有显著性能提升。
检查测试过程中的堆栈,发现可疑线程:

奇怪的慢优化1.png

奇怪的慢优化2.png

发现实际 DELETE 语句运行过程中存在 CSCN 以及 SLCT 操作符,怀疑是绑定参数的类型不一致导致计划存在问题

随后通过 TRACE DUMP PLN,得到实际执行计划:

奇怪的慢优化3.png

没有问题,多次清理执行计划,并跟踪 10053,发现 DELETE 计划正常。
后重启服务器,设置 10003 事件,监控 CSCN 操作符,得到一些语句,但是语句并没有测试中的 DELETE 语句,说明 DELETE 语句确实计划正常

由于相关线程又存在计划中不存在的操作符,怀疑是触发器或者外键影响。

通过检查 SYSOBJECTS 未发现行级触发器,随后检查外键,发现有大量表的外键引用到待删除表的主键。由于我们默认外键是没有索引的,级联删除时可能出现依赖表也有 DELETE 操作并且无索引可用的情况。

拉出几个外键定义查看后,发现确实没有 WITH INDEX 选项,随后将相关外键都添加 INDEX,再次进行测试,性能正常

该问题跟踪过程中,在压测时 MANAGER 执行 DELETE 速度正常,是因为外键触发的级联操作是在事务提交时才会触发,类似触发器,所以导致一定的误解。
另外大量 DELETE/UPD 时,对回滚段的需求会很大的,调小 UNDO RENTETION,改大 UNDO EXTENT NUM 可以避免在 DML 过程中向回滚段申请新段从而触发回滚段封锁等影响并发的动作。

这里给出现场同事后续编写的一个脚本,用于批量修改外键约束 WITH INDEX :

--添加外键索引 SELECT 'alter table "' ||t1.table_NAME ||'" modify constraint "' ||t1.CONSTRAINT_NAME ||'" to foreign key("' ||t3.COLUMN_NAME ||'") references "' ||t2.table_name ||'"("' ||t4.column_name ||'") with index;' /*t1.owner AS FK_OWNER, t1.table_name AS FK_TABLE, t1.constraint_name AS FK , t3.column_name AS FK_COL , T2.OWNER AS PK_OWNER, t2.table_name AS PK_TABLE, t1.r_constraint_name AS PK , t4.column_name AS PK_COL, T1.DELETE_RULE*/ from dba_constraints t1 , dba_constraints t2 , DBA_CONS_COLUMNS t3, DBA_CONS_COLUMNS T4 where t1.constraint_type='R' and t2.constraint_type='P' and t2.constraint_name=t1.r_constraint_name and t3.constraint_name=t1.constraint_name AND T2.constraint_name=T4.constraint_name and t2.table_name ='表名'
评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服