外键无索引引发的血案
一、故障现象
周末接到一个CASE,故障描述是,当时业务产生大量的TX锁,DBA因为不怎么了解,锁的原理,盲目的KILL 进程,无法尽快的定位问题。为了不影响业务,重启了数据库,导致大量的用户投诉。
创新互联专注于大城企业网站建设,响应式网站设计,商城网站建设。大城网站建设公司,为大城等地区提供建站服务。全流程按需定制设计,专业设计,全程项目跟踪,创新互联专业和态度为您提供的服务
Fri Mar 13 15:05:17 2020
opiodr aborting process unknown ospid (33292328) as a result of ORA-28
Fri Mar 13 15:05:59 2020
opiodr aborting process unknown ospid (34668796) as a result of ORA-28
Fri Mar 13 15:06:11 2020
opiodr aborting process unknown ospid (33554618) as a result of ORA-28
Fri Mar 13 15:06:23 2020
opiodr aborting process unknown ospid (34471986) as a result of ORA-28
Fri Mar 13 15:06:45 2020
二、分析过程
1从awrtop 等待事件看,产生大量的TX
2awr top sql
3 ASH 分析
从awr看当时阻塞的应该是insert语句导致,awr执行语句比较长的
而awr中放在首位的是UPDATA及DELETE,没有办法继续看ash一些内容,发现如下表使用比较高,
而在awr中,无此表的相关语句,
从上边分析看出,锁住的有insert语句,因此怀疑为外键没有索引导致。
查看表的结构。
如下:
DELETE FROM bTT WHERE id_=:1 引起的,并且 在task_id 字段上不存在索引,
三、结论
添加表索引后问题解决,再也没有出现过大量enq锁
四、总结
在ORACLE数据库中,定义外键约束时,ORACLE是不会自动创建对应索引的,必须手动在外键约束相关的列上创建索引。
外键缺失索引影响
外键列上缺少索引会带来三个问题,限制并发性、影响性能、还有可能造成死锁。所以对于绝大部分场景,我们应该尽量考虑在外键上面创建索引
影响性能。如果子表外键没有创建索引,那么当父表查询关联子表时,子表将进行全表扫描。影响表连接方式。
影响并发。无论是更新父表主键,或者删除一个父记录,都会在子表中加一个表锁(在这条语句完成前,不允许对子表做任何修改)。这就会不必要地锁定更多的行,而影响并发性
3. 在特殊情况下,还有可能造成死锁。
不需要对外键建索引,满足的条件如下:
1. 不会删除父表中的行。
2. 不论是有意还是无意,总之不会更新父表 的唯一 / 主键字段值。
3. 不会从父表联结到子表, 或者更通俗的讲,外键列不支持子表的一个重要访问路径,而且你在谓词中没有使用这些外键累从子表中选择数据 。
文章标题:外键无索引引发的血案
文章起源:http://ybzwz.com/article/pihdjh.html