ITPub博客

首页 > 数据库 > Oracle > 外键无索引引发的血案

外键无索引引发的血案

原创 Oracle 作者:pingdanorcale 时间:2020-04-26 17:41:38 0 删除 编辑
一、故障现象

     周末接到一个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是不会自动创建对应索引的,必须手动在外键约束相关的列上创建索引。 

外键缺失索引影响

外键列上缺少索引会带来三个问题,限制并发性、影响性能、还有可能造成死锁。所以对于绝大部分场景,我们应该尽量考虑在外键上面创建索引

  1. 影响性能。如果子表外键没有创建索引,那么当父表查询关联子表时,子表将进行全表扫描。影响表连接方式。

  2. 影响并发。无论是更新父表主键,或者删除一个父记录,都会在子表中加一个表锁(在这条语句完成前,不允许对子表做任何修改)。这就会不必要地锁定更多的行,而影响并发性

  3. 在特殊情况下,还有可能造成死锁。

不需要对外键建索引,满足的条件如下:

1. 不会删除父表中的行。

2. 不论是有意还是无意,总之不会更新父表 的唯一 / 主键字段值。

3.  不会从父表联结到子表,  或者更通俗的讲,外键列不支持子表的一个重要访问路径,而且你在谓词中没有使用这些外键累从子表中选择数据


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10201716/viewspace-2688533/,如需转载,请注明出处,否则将追究法律责任。

全部评论

注册时间:2009-01-02

  • 博文量
    34
  • 访问量
    85890