ITPub博客

首页 > 数据库 > Oracle > 外键一定要加索引

外键一定要加索引

原创 Oracle 作者:壹頁書 时间:2013-12-28 14:34:52 0 删除 编辑
Mysql创建外键约束会自动创建一个索引,但是Oracle不会这样做。
所以Oracle在创建外键之后,一定要手动创建索引。
如果没有在外键上创建索引,会经常遇到如下问题。
1.死锁
    
  1. --创建实验表
  2. create table emp as select * from hr.employees;
  3. create table dept as select * from hr.departments;
  4. alter table emp add constraint pk_emp primary key (employee_id);
  5. alter table dept add constraint pk_dept primary key (department_id);
  6. alter table emp add constraint fk_emp_dept foreign key (department_id) references dept(department_id) on delete cascade;
    如果删除任意一条Emp表的记录,都会导致dept表的所有记录不能删除。
    
    SessionA,删除任意一条Emp表记录,不提交

    
    另一个SessionB,他删除任何dept表的记录,都会被阻塞。


    当然,对Dept表的插入和更新不受影响
    (假设不更新主键字段)

2.性能下降
    查询某个部门的员工信息。
  1. select employee_id,dept.department_name,first_name
  2. from dept
  3. inner join emp
  4. on emp.department_id=dept.department_id
  5. where emp.department_id=80;
    如果没有索引,则emp表全表扫描
    
    如果外键建立索引,则优化的效果显而易见
    

下面是Tom给出的脚本,检查外键无索引的表

  1. COLUMN COLUMNS format a30 word_wrapped
  2. COLUMN tablename format a15 word_wrapped
  3. COLUMN constraint_name format a15 word_wrapped
  4. SELECT TABLE_NAME,
  5.        CONSTRAINT_NAME,
  6.        CNAME1 || NVL2(CNAME2, ',' || CNAME2, NULL) ||
  7.        NVL2(CNAME3, ',' || CNAME3, NULL) ||
  8.        NVL2(CNAME4, ',' || CNAME4, NULL) ||
  9.        NVL2(CNAME5, ',' || CNAME5, NULL) ||
  10.        NVL2(CNAME6, ',' || CNAME6, NULL) ||
  11.        NVL2(CNAME7, ',' || CNAME7, NULL) ||
  12.        NVL2(CNAME8, ',' || CNAME8, NULL) COLUMNS
  13.   FROM (SELECT B.TABLE_NAME,
  14.                B.CONSTRAINT_NAME,
  15.                MAX(DECODE(POSITION, 1, COLUMN_NAME, NULL)) CNAME1,
  16.                MAX(DECODE(POSITION, 2, COLUMN_NAME, NULL)) CNAME2,
  17.                MAX(DECODE(POSITION, 3, COLUMN_NAME, NULL)) CNAME3,
  18.                MAX(DECODE(POSITION, 4, COLUMN_NAME, NULL)) CNAME4,
  19.                MAX(DECODE(POSITION, 5, COLUMN_NAME, NULL)) CNAME5,
  20.                MAX(DECODE(POSITION, 6, COLUMN_NAME, NULL)) CNAME6,
  21.                MAX(DECODE(POSITION, 7, COLUMN_NAME, NULL)) CNAME7,
  22.                MAX(DECODE(POSITION, 8, COLUMN_NAME, NULL)) CNAME8,
  23.                COUNT(*) COL_CNT
  24.           FROM (SELECT SUBSTR(TABLE_NAME, 1, 30) TABLE_NAME,
  25.                        SUBSTR(CONSTRAINT_NAME, 1, 30) CONSTRAINT_NAME,
  26.                        SUBSTR(COLUMN_NAME, 1, 30) COLUMN_NAME,
  27.                        POSITION
  28.                   FROM USER_CONS_COLUMNS) A,
  29.                USER_CONSTRAINTS B
  30.          WHERE A.CONSTRAINT_NAME = B.CONSTRAINT_NAME
  31.            AND B.CONSTRAINT_TYPE = 'R'
  32.          GROUP BY B.TABLE_NAME, B.CONSTRAINT_NAME) CONS
  33.  WHERE COL_CNT > ALL
  34.  (SELECT COUNT(*)
  35.           FROM USER_IND_COLUMNS I
  36.          WHERE I.TABLE_NAME = CONS.TABLE_NAME
  37.            AND I.COLUMN_NAME IN (CNAME1, CNAME2, CNAME3, CNAME4, CNAME5,
  38.                 CNAME6, CNAME7, CNAME8)
  39.            AND I.COLUMN_POSITION <= CONS.COL_CNT
  40.          GROUP BY I.INDEX_NAME)
  41. /

参考:
http://blog.csdn.net/dba_waterbin/article/details/9045483

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

请登录后发表评论 登录
全部评论

注册时间:2013-10-19

  • 博文量
    620
  • 访问量
    6339892