再一次强调,ORACLE外键必须加索引
外键加索引是常识,必须牢记。本来不想写这样的简单案例。可是连续遇到好几起外键不加索引导致性能问题,所以还是写一下。
一个兄弟问我 delete from Sa_Sales_Comm_Detail s where s.sales_commission_id=24240; ---删除105条数据很慢。要跑几十秒到上百秒
这个表总数据才35万行,sales_commission_id 列有索引,运行计划也确实是走了索引。 走索引返回105 条数据。不可能跑几十秒跑上百秒的。
之后我问他 select * from Sa_Sales_Comm_Detail s where s.sales_commission_id=24240; 这个跑得慢吗。他回答 0.06秒。
select * from Sa_Sales_Comm_Detail s where s.sales_commission_id=24240; ---0.06秒
delete from Sa_Sales_Comm_Detail s where s.sales_commission_id=24240; ---几十秒几百秒
遇到这样的,直接做10046 trace,部分的trace文件例如以下
=====================
PARSING IN CURSOR #4 len=111 dep=1 uid=0 oct=3 lid=0 tim=1374414810328412 hv=4234506700 ad='99cc8678'
select /*+ all_rows */ count(1) from "CMM"."SA_SALES_PER_SPLIT_DETAIL" where "SALES_COMMISSION_DETAIL_ID" = :1
END OF STMT
PARSE #4:c=4000,e=4619,p=0,cr=0,cu=2,mis=1,r=0,dep=1,og=1,tim=1374414810328406
EXEC #4:c=999,e=1841,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=1,tim=1374414810330416
FETCH #4:c=226965,e=221384,p=0,cr=6867,cu=0,mis=0,r=1,dep=1,og=1,tim=1374414810551844
=====================
PARSING IN CURSOR #2 len=106 dep=1 uid=0 oct=3 lid=0 tim=1374414810557316 hv=1936840180 ad='8ae35660'
select /*+ all_rows */ count(1) from "CMM"."SA_SALES_COMM_REPROT" where "SALES_COMMISSION_DETAIL_ID" = :1
END OF STMT
PARSE #2:c=5000,e=5152,p=0,cr=0,cu=2,mis=1,r=0,dep=1,og=1,tim=1374414810557310
EXEC #2:c=3000,e=2081,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=1,tim=1374414810559571
WAIT #2: nam='db file scattered read' ela= 384 file#=5 block#=83604 blocks=5 obj#=104150 tim=1374414810560401
WAIT #2: nam='db file scattered read' ela= 154 file#=5 block#=87785 blocks=8 obj#=104150 tim=1374414810561125
WAIT #2: nam='db file scattered read' ela= 141 file#=5 block#=87802 blocks=7 obj#=104150 tim=1374414810561384
WAIT #2: nam='db file scattered read' ela= 204 file#=5 block#=94633 blocks=8 obj#=104150 tim=1374414810561704
WAIT #2: nam='db file scattered read' ela= 160 file#=5 block#=94642 blocks=7 obj#=104150 tim=1374414810562029
WAIT #2: nam='db file scattered read' ela= 167 file#=5 block#=94649 blocks=8 obj#=104150 tim=1374414810562309
WAIT #2: nam='db file scattered read' ela= 184 file#=5 block#=94674 blocks=7 obj#=104150 tim=1374414810562602
WAIT #2: nam='db file scattered read' ela= 172 file#=5 block#=94705 blocks=8 obj#=104150 tim=1374414810562882
WAIT #2: nam='db file scattered read' ela= 135 file#=5 block#=94714 blocks=7 obj#=104150 tim=1374414810563132
WAIT #2: nam='db file scattered read' ela= 162 file#=5 block#=97529 blocks=8 obj#=104150 tim=1374414810563412
WAIT #2: nam='db file scattered read' ela= 234 file#=5 block#=98314 blocks=7 obj#=104150 tim=1374414810563758
WAIT #2: nam='db file scattered read' ela= 154 file#=5 block#=99513 blocks=8 obj#=104150 tim=1374414810564008
WAIT #2: nam='db file scattered read' ela= 143 file#=5 block#=101666 blocks=7 obj#=104150 tim=1374414810564260
WAIT #2: nam='db file scattered read' ela= 166 file#=5 block#=101681 blocks=8 obj#=104150 tim=1374414810564533
WAIT #2: nam='db file scattered read' ela= 157 file#=5 block#=101690 blocks=7 obj#=104150 tim=1374414810564797
WAIT #2: nam='db file scattered read' ela= 128 file#=5 block#=101697 blocks=8 obj#=104150 tim=1374414810565025
WAIT #2: nam='db file scattered read' ela= 335 file#=5 block#=102027 blocks=16 obj#=104150 tim=1374414810565576
WAIT #2: nam='db file scattered read' ela= 355 file#=5 block#=102043 blocks=16 obj#=104150 tim=1374414810566148
WAIT #2: nam='db file scattered read' ela= 302 file#=5 block#=102059 blocks=16 obj#=104150 tim=1374414810566690
WAIT #2: nam='db file scattered read' ela= 323 file#=5 block#=102075 blocks=16 obj#=104150 tim=1374414810567221
WAIT #2: nam='db file scattered read' ela= 310 file#=5 block#=102091 blocks=16 obj#=104150 tim=1374414810567720
WAIT #2: nam='db file scattered read' ela= 270 file#=5 block#=102107 blocks=16 obj#=104150 tim=1374414810568243
WAIT #2: nam='db file scattered read' ela= 378 file#=5 block#=102123 blocks=16 obj#=104150 tim=1374414810568814
WAIT #2: nam='db file scattered read' ela= 253 file#=5 block#=102139 blocks=14 obj#=104150 tim=1374414810569252
WAIT #2: nam='db file scattered read' ela= 527 file#=5 block#=108043 blocks=16 obj#=104150 tim=1374414810570016
WAIT #2: nam='db file scattered read' ela= 309 file#=5 block#=108059 blocks=16 obj#=104150 tim=1374414810570543
WAIT #2: nam='db file scattered read' ela= 281 file#=5 block#=108075 blocks=16 obj#=104150 tim=1374414810571075
WAIT #2: nam='db file scattered read' ela= 356 file#=5 block#=108091 blocks=16 obj#=104150 tim=1374414810571658
WAIT #2: nam='db file scattered read' ela= 273 file#=5 block#=108107 blocks=16 obj#=104150 tim=1374414810572138
WAIT #2: nam='db file scattered read' ela= 381 file#=5 block#=108123 blocks=16 obj#=104150 tim=1374414810572715
WAIT #2: nam='db file scattered read' ela= 318 file#=5 block#=108139 blocks=16 obj#=104150 tim=1374414810573241
WAIT #2: nam='db file scattered read' ela= 302 file#=5 block#=108155 blocks=14 obj#=104150 tim=1374414810573745
WAIT #2: nam='db file scattered read' ela= 280 file#=5 block#=109195 blocks=16 obj#=104150 tim=1374414810574226
WAIT #2: nam='db file scattered read' ela= 362 file#=5 block#=109211 blocks=16 obj#=104150 tim=1374414810574795
WAIT #2: nam='db file scattered read' ela= 333 file#=5 block#=109227 blocks=16 obj#=104150 tim=1374414810575357
WAIT #2: nam='db file scattered read' ela= 331 file#=5 block#=109243 blocks=16 obj#=104150 tim=1374414810575904
WAIT #2: nam='db file scattered read' ela= 377 file#=5 block#=109259 blocks=16 obj#=104150 tim=1374414810576483
WAIT #2: nam='db file scattered read' ela= 349 file#=5 block#=109275 blocks=16 obj#=104150 tim=1374414810577059
WAIT #2: nam='db file scattered read' ela= 344 file#=5 block#=109291 blocks=16 obj#=104150 tim=1374414810577601
WAIT #2: nam='db file scattered read' ela= 320 file#=5 block#=109307 blocks=14 obj#=104150 tim=1374414810578133
WAIT #2: nam='db file scattered read' ela= 385 file#=7 block#=2699 blocks=16 obj#=104150 tim=1374414810578830
从trace文件中面看到。运行delete的时候。隐含的调用了
select /*+ all_rows */ count(1) from "CMM"."SA_SALES_COMM_REPROT" where "SALES_COMMISSION_DETAIL_ID" = :1
这个sql 导致了 db file scattered read(多块读) ,也就是说 上面的sql 没走索引,走了全表扫描 ,于是让他在 SALES_COMMISSION_DETAIL_ID 列上面建立索引
建立索引之后,delete仅仅须要0.几秒就可以。
反正记住。外键上面要建立索引。
再一次强调,ORACLE外键必须加索引的更多相关文章
- Oracle外键需要建索引吗?
关于Oracle中的外键,首先要说明一下. 1. 除非已定义了父表主键或唯一键约束,否则oracle将不允许创建子表的外键约束. 2. 在定义外键约束时,oracle不会自动创建索引,所以必须手动在与 ...
- ORACLE外键和锁
在oracle中,如果外键未加索引,对父表的修改,会导致子表被加上全表锁.这包括两种情况: 1.删除父表中的行,如果外键上没有索引,会导致子表被加上全表锁 2.更新父表的主键(根据关系数据库的原则,更 ...
- 通过在Oracle子表外键上建立索引提高性能
根据我的经验,导致死锁的头号原因是外键未加索引(第二号原因是表上的位图索引遭到并发更新).在以下两种情况下,Oracle在修改父表后会对子表加一个全表锁: 1)如果更新了父表的主键(倘若遵循关系数据库 ...
- Oracle外键不加索引会引起死锁问题
转载链接:http://www.jb51.net/article/50161.htm 这篇文章主要介绍了Oracle外键不加索引引起死锁的情况及解决,需要的朋友可以参考下 --创建一个表,此表作为子表 ...
- 关于 Oracle外键列上是否需要索引问题?
外键列上缺少索引会带来两个问题,限制并发性.影响性能.而这两个问题中的任意一个都可能会造成严重性能问题. 无论是Oracle的官方文档,还是在Tom的书中都说明了两种情况下可以忽略外键上的索引.其 ...
- Oracle外键(Foreign Key)使用详细的说明(一)
Oracle外键(Foreign Key)使用详细的说明(一) 1.目标 演示如何Oracle使用外键数据库 2.什么是外键? 1)在Oracle数据库中,外键是用来实现參照完整性的方法之中的一个.打 ...
- Oracle 外键约束
本文讨论一下Oracle中的外键约束问题,以及和DB2中的小不同. 首先创建测试环境. -- 创建测试主表. ID 是主键. CREATE TABLE test_main ( id INT, valu ...
- Oracle 外键级联更新
Oracle数据库中,外键约束只允许级联删除,不允许级联更新,因此,如果想要实现主表数据更新后,子表外键自动更新,只能取消外键关系,通过前端程序来维护实现完整引用,一个代替的解决方案是使用延迟约束和触 ...
- mysql添加外键约束变为索引
今天有位自己填上一坑:mysql储存引擎 原因就是数据库表引擎为:MyISAM,建立主外键关系需要是InnoDB: 解决方案:alter table table_name1 engine=inno ...
随机推荐
- IOS详解TableView——选项抽屉(天猫商品列表)
在之前的有篇文章讲述了利用HeaderView来写类似QQ好友列表的表视图. 这里写的天猫抽屉其实也可以用该方法实现,具体到细节每个人也有所不同.这里采用的是点击cell对cell进行运动处理以展开“ ...
- C#基础:关键字和数据类型
[关键字] #region 和 #endregion 关键字可以折叠代码 checked 用于整型算术运算时控制当前环境中的溢出检查 unchecked 操作符用于整型算术运算时控制当前环境中的 ...
- (转)Javascript面向对象编程(二):构造函数的继承(作者:阮一峰)
对象之间的"继承"的五种方法. 比如,现在有一个"动物"对象的构造函数. function Animal(){ this.species = "动物& ...
- Socket与TcpClient的区别(转载)
Socket和TcpClient有什么区别 原文:http://wxwinter.spaces.live.com/blog/cns!C36588978AFC344A!322.entry 回答: &qu ...
- jquery easyui-datagrid 如何清空数据
//清空原有数据 方法1: var item = $('#filegrid').datagrid('getRows'); if (item) { ; i >= ; i--) { var in ...
- AVT Vimba与OpenCV环境配置
近来,由于项目需求,需要使用AVT的一款相机采集图像并进行相应的算法处理.环境的配置过程较为复杂,特此记录,以做备忘.也给有需要的小伙伴们一些key point的分享. 搭建环境:Windows7 + ...
- Javascript判断空对象
最近在项目开发中判断空对象时,用了“!”运算符,结果程序出现bug,找了好久才找到原因. 其实自己范了一些低级错误,现在把自己经验总结一下: 在JavaScript中,任意JavaScript的值都可 ...
- 学习MVC框架之一
一.MVC的概述 MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑和数据显示分离的 ...
- (原)python中import caffe提示no module named google.protobuf.internal
转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5993405.html 之前在一台台式机上在python中使用import caffe时,没有出错.但是 ...
- Java中循环删除list中元素的方法总结
印象中循环删除list中的元素使用for循环的方式是有问题的,但是可以使用增强的for循环,然后在今天使用的时候发现报错了,然后去科普了一下,发现这是一个误区.下面我们来一起看一下. Java中循环遍 ...