oracle外键有什么用,深入理解Oracle索引(20):外键是否应该加索引
先表明我的立场、我是绝对支持外键一定要加索引!
虽然在高版本的Oracle里、对这个要求有所降低、但依然有如下原因:
① 死锁
外键未加索引是导致死锁的最主要原因、因为
无论更新父表主键、或者删除一个父表记录、都会在子表加一个表锁
这就会不必要的锁定更多的行、从而影响并发性
② ON DELETE CASCADE
对于删除的每一个父行、都会把子表全表扫描一次
如:
EMP是DEPT的子表
DELETE dept WHERE deptno=10 会级联至EMP
③ 从父表查询子表
如:
EMP是DEPT的子表
SELECT *
FROM dept,emp
WHERE emp.deptno=dept.deptno and
dept.dname= :X
另外、证明子表由于外键未加索引而被锁住、可经由下列方法:
ALTER TABLE DISABLE TABLE LOCK;
那么、对父表的可能导致表锁的任何 UPDATE 或 DELETE 都会收到如下错误:
ERROR at line 1:
ORA-00069: cannot acquire lock -- table locks disable for
以下做个简单的外键未加索引的测试:
建立表:
hr@ORCL> create table t_father (id number,name varchar2(25),primary key(id));
hr@ORCL> create table t_sun (fid number,name varchar2(25),foreign key(fid) references t_father(id));
hr@ORCL> select table_name,CONSTRAINT_NAME,STATUS,R_CONSTRAINT_NAME from user_constraints where owner=\'HR\' and table_name in (\'T_FATHER\',\'T_SUN\');
TABLE_NAME CONSTRAINT_NAME STATUS R_CONSTRAINT_NAME
------------------------------ ------------------------------ -------- ------------------------------
T_FATHER SYS_C005495 ENABLED
T_SUN SYS_C005497 ENABLED SYS_C005495
倒入数据并分析表:
hr@ORCL> insert into t_father select rownum,rownum||\'a\' from dual connect by rownum<1000;
hr@ORCL> insert into t_sun select rownum,rownum||\'b\' from dual connect by rownum<1000;
hr@ORCL> commit;
hr@ORCL> exec dbms_stats.gather_table_stats(ownname=>\'HR\',tabname=>\'T_FATHER\');
hr@ORCL> exec dbms_stats.gather_table_stats(ownname=>\'HR\',tabname=>\'T_SUN\');
用以下 TOM 给出的脚本检查外键无索引的表:
COLUMN COLUMNS format a30 word_wrapped
COLUMN tablename format a15 word_wrapped
COLUMN constraint_name format a15 word_wrapped
SELECT TABLE_NAME,
CONSTRAINT_NAME,
CNAME1 || NVL2(CNAME2, \',\' || CNAME2, NULL) ||
NVL2(CNAME3, \',\' || CNAME3, NULL) ||
NVL2(CNAME4, \',\' || CNAME4, NULL) ||
NVL2(CNAME5, \',\' || CNAME5, NULL) ||
NVL2(CNAME6, \',\' || CNAME6, NULL) ||
NVL2(CNAME7, \',\' || CNAME7, NULL) ||
NVL2(CNAME8, \',\' || CNAME8, NULL) COLUMNS
FROM (SELECT B.TABLE_NAME,
B.CONSTRAINT_NAME,
MAX(DECODE(POSITION, 1, COLUMN_NAME, NULL)) CNAME1,
MAX(DECODE(POSITION, 2, COLUMN_NAME, NULL)) CNAME2,
MAX(DECODE(POSITION, 3, COLUMN_NAME, NULL)) CNAME3,
MAX(DECODE(POSITION, 4, COLUMN_NAME, NULL)) CNAME4,
MAX(DECODE(POSITION, 5, COLUMN_NAME, NULL)) CNAME5,
MAX(DECODE(POSITION, 6, COLUMN_NAME, NULL)) CNAME6,
MAX(DECODE(POSITION, 7, COLUMN_NAME, NULL)) CNAME7,
MAX(DECODE(POSITION, 8, COLUMN_NAME, NULL)) CNAME8,
COUNT(*) COL_CNT
FROM (SELECT SUBSTR(TABLE_NAME, 1, 30) TABLE_NAME,
SUBSTR(CONSTRAINT_NAME, 1, 30) CONSTRAINT_NAME,
SUBSTR(COLUMN_NAME, 1, 30) COLUMN_NAME,
POSITION
FROM USER_CONS_COLUMNS) A,
USER_CONSTRAINTS B
WHERE A.CONSTRAINT_NAME = B.CONSTRAINT_NAME
AND B.CONSTRAINT_TYPE = \'R\'
GROUP BY B.TABLE_NAME, B.CONSTRAINT_NAME) CONS
WHERE COL_CNT > ALL
(SELECT COUNT(*)
FROM USER_IND_COLUMNS I
WHERE I.TABLE_NAME = CONS.TABLE_NAME
AND I.COLUMN_NAME IN (CNAME1, CNAME2, CNAME3, CNAME4, CNAME5,
CNAME6, CNAME7, CNAME8)
AND I.COLUMN_POSITION <= CONS.COL_CNT
GROUP BY I.INDEX_NAME)
/
hr@ORCL> /
TABLE_NAME CONSTRAINT_NAME COLUMNS
------------------------------ --------------- ------------------------------
T_SUN SYS_C005497 FID
以下进行测试:
1)Session_A:
hr@ORCL> select sid from v$session where sid in (select sid from v$mystat where rownum=1);
SID
----------
159
hr@ORCL> delete t_sun where fid=998;
1 row deleted.
2)Session_B:
hr@ORCL> select sid from v$session where sid in (select sid from v$mystat where rownum=1);
SID
----------
142
hr@ORCL> delete t_sun where fid=123;
1 row deleted.
3)Session_A:
hr@ORCL> delete t_father where id=555;
----请求子表的表锁却不可得之、被hang住了
用下面脚本查询数据库锁情况:
SELECT a.sid ||
decode(request,
0,
\' :holder\',\' :Waiter\') sess_id,blocking_session blocker,
lmode,
request,
a.type,
c.object_name,
decode(row_wait_obj#,
-1,
\'Holder of Lock !!!\',
dbms_rowid.rowid_create(1,
row_wait_obj#,
row_wait_file#,
row_wait_block#,
row_wait_row#)) row_id,
nvl(SQL_FULLTEXT, \'Holder of Lock !!!\') sqltext
FROM V$LOCK A, V$LOCKED_OBJECT B, ALL_OBJECTS C, V$SESSION D, V$SQL E
WHERE (id1, id2, a.type) in
(select id1, id2, type from v$lock where request > 0)
AND a.sid = b.session_id
AND b.object_id = c.object_id
AND d.sid = a.sid
AND d.sql_hash_value = e.hash_value(+)
sys@ORCL> /
SESS_ID BLOCKER LMODE REQUEST TY OBJECT_NAME ROW_ID SQLTEXT
------------------------------------------------ ---------- ---------- ---------- -- ------------------------------ ------------------ --------------------------------------------------------------------------------
159 :Waiter 142 3 5 TM T_SUN Holder of Lock !!! delete t_father where id=555
159 :Waiter 142 3 5 TM T_FATHER Holder of Lock !!! delete t_father where id=555
142 :holder 3 0 TM T_SUN Holder of Lock !!! Holder of Lock !!!
142 :holder 3 0 TM T_FATHER Holder of Lock !!! Holder of Lock !!!
By David Lin
2013-06-07
Good Luck
oracle外键有什么用,深入理解Oracle索引(20):外键是否应该加索引相关推荐
- oracle监听显示未成功_理解 oracle 的 lsnrctl status
理解 oracle 的 "lsnrctl status" 先看看 lsnrctl status 的输出信息: Services Summary... Service "P ...
- oracle_sqlserver和mysql获取表外键的方法_mysql、sqlserver、oracle三种数据库维护索引、外键、字段语法总结...
mysql.sqlserver.oracle三种数据库维护索引.外键.字段语法总结 1. MYSQL数据库 1) 创建索引 CREATE INDEX index_name ON tabl ...
- oracle 建立外键 引用条件约束 不能添加,Oracle外键约束
一.创建外键约束 两种方法 1.创建表时 create table 子表( id number, name varchar2(5), foreign key(id) references 父表(列名) ...
- 深入理解Oracle RAC 12c 笔记
深入理解Oracle RAC 12c 跳转至: 导航. 搜索 文件夹 1 概述 2 集群件管理和故障诊断 3 执行实践 4 新特性 5 存储和ASM 6 应用设计上的问题 7 管理和调优一个复杂的RA ...
- 《深入理解Oracle 12c数据库管理(第二版)》PDF
一:下载获取位置: 二:本书图样: 三:本书目录: 图书目录: 第1章 安装Oracle 1.1 了解OFA 1.1.1 Oracle清单目录 1.1.2 Oracle基础目录 1.1.3 Oracl ...
- 深入理解Oracle的并行操作
并行(Parallel)和OLAP系统 并行的实现机制是:首先,Oracle会创建一个进程用于协调并行服务进程之间的信息传递,这个协调进程将需要操作的数据集(比如表的数据块)分割成很多部分,称为并行 ...
- 深入理解Oracle的并行操作【好文认真读】
请尊重原文作者,http://czmmiao.iteye.com/blog/1487568 ------------------------------------------------------ ...
- oracle 主键_mysql 组合索引带主键ID的问题
场景: mysql 5.7 某表 t_apply_info 上的2个索引,一个组合索引带了 主键字段 ID,另一个是同字段的单列索引 例如: KEY idx_1 (apply_serial_no,id ...
- sql语句的内连接、左外连接、右外连接的理解
sql语句 内连接.左外连接.右外连接的理解 大家在初学数据库时,对DQL中的连接查询是否有些疑惑,不知道什么时候什么场景下该用那种连接查询? 不要着急,接下来由我来给大家介绍一下,本人对内连接.左外 ...
最新文章
- ubuntu 启动器
- 从源码安装GDB-8.1
- JDK版本不匹配...
- 中文自然语言处理(NLP)(三)运用python jieba模块计算知识点当中关键词的词频
- C++ 普通函数与函数模板 区别以及调用规则01
- Leetcode每日一题:80.remove-duplicates-from-sorted-array-ii(删除排序数组中的重复项Ⅱ)
- OC中的@的作用研究
- 台式计算机文件打不开怎么回事,电脑文件打不开怎么回事
- html的九宫格构图教学视频,构图的基本技巧之九宫格构图
- 罗永浩如果倒过来过,也很励志
- win中q-dir,everything,Windows Tabs,Clover各种效率神器(搜索,资源管理器,多标签)
- 微信小游戏接入遇到的坑
- 笔记本电脑触摸板无法使用(失灵)解决方案 (win10和win7通用)
- linux串口操作及设置
- 1553B总线基础知识及扩展
- [RelativeNAS] Relative Neural Architecture Search via Slow-Fast Learning
- 计算机一级office考试攻略,计算机一级考试MSOffice应试技巧
- IDEA 查找某个 jar 包是如何被引入的
- 安装画图工具kolourpaint
- 【环境搭建】WAMP环境+DVWA漏洞测试平台搭建过程
热门文章
- jedispool redis哨兵_Redis详解(九)------ 哨兵(Sentinel)模式详解
- C#命名空间namespace中不能直接包含字段(变量)或方法(函数)之类的成员
- 上海工程技术大学c语言,上海工程技术大学 C语言实习报告.doc
- python怎么创建变量_python怎么创建变量
- 六西格玛dfss_六西格玛系列知识之二:六西格玛管理的基本原理
- rapidxml在qt linux(gcc)下写xml文件出错
- MFC之CAsyncSocket详解
- 矩阵运算——平移,旋转,缩放
- TI Sitara AM335x系统之AM335x uboot spl分析
- java构建内存池队列_内存池完整实现代码及一些思考