1. 程式人生 > >兩表關聯查詢-創建約束,外鍵對比

兩表關聯查詢-創建約束,外鍵對比

報錯 loop ant 不存在 source evel ann 開啟 statistic

--開啟執行計劃:

set autotrace on

SP2-0618: Cannot find the Session Identifier. Check PLUSTRACE role is enabled

找不到會話標識符,啟用檢查
SP2-0611: Error enabling STATISTICS report

錯誤:統計報告

grant plustrace to scott
*
ERROR at line 1:
ORA-01919: role ‘PLUSTRACE‘ does not exist ---角色不存在


SQL> select * from dba_roles where role=‘PLUSTRACE‘; ---查詢角色

no rows selected

SQL> @?/sqlplus/admin/plustrce.sql -----執行腳本
SQL> drop role plustrace;
drop role plustrace
*
ERROR at line 1:
ORA-01919: role ‘PLUSTRACE‘ does not exist


SQL> create role plustrace;

Role created.

SQL> grant select on v_$sesstat to plustrace;

Grant succeeded.

SQL> grant select on v_$statname to plustrace;

Grant succeeded.

SQL> grant select on v_$mystat to plustrace;

Grant succeeded.

SQL> grant plustrace to dba with admin option;

Grant succeeded.

SQL> set echo off

-----------------------------

grant plustrace to scott;

SQL> select USERNAME,GRANTED_ROLE from user_role_privs;

USERNAME GRANTED_ROLE
------------------------------ ------------------------------
SCOTT CONNECT
SCOTT PLUSTRACE
SCOTT RESOURCE

----這是最後的:類似的查詢;

select empno,ename,sal from scott.emp e,scott.dept d where e.deptno=d.deptno;

--生成測試:

SQL> create table emp1 as select * from emp;

SQL> create table dept2 as select * from dept;

**********測試查詢一(兩個表,沒有索引,沒有約束)*********************************

SQL> set autotrace traceonly;
SQL> select empno,ename,sal from emp1 e,dept2 d where e.deptno=d.deptno;

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 826 | 6 (0)| 00:00:01 |
|* 1 | HASH JOIN | | 14 | 826 | 6 (0)| 00:00:01 |
| 2 | TABLE ACCESS FULL| DEPT2 | 4 | 52 | 3 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL| EMP1 | 14 | 644 | 3 (0)| 00:00:01 |

1 - access("E"."DEPTNO"="D"."DEPTNO")

Note
-----
dynamic sampling used for this statement (level=2)

7 consistent gets

exec dbms_stats.gather_table_stats(ownname=>‘SCOTT‘,tabname=>‘EMP1‘);

*****************************************測試查詢二(dept2表中建立了主鍵約束(建立了索引))*******************************************

--創建外鍵約束:

alter table emp1 add constraint emp_forkey foreign key(deptno) references dept2(deptno)
*
ERROR at line 1:
ORA-02270: no matching unique or primary key for this column-list

--沒有匹配的這個列表唯一或主鍵

子表創建與父表的:外鍵約束,必須要明確父表關聯列,有主鍵或者唯一約束;

SQL> alter table dept2 add constraint p_k primary key(deptno);

SQL> select owner,constraint_name from user_constraints ;

OWNER CONSTRAINT_NAME
-------------------- --------------------
SCOTT P_K

SQL> select INDEX_NAME,TABLE_NAME from user_indexes;

INDEX_NAME TABLE_NAME
------------------------------ ------------------------------
P_K DEPT2

--建立主鍵約束後,父表dept2,的列deptno列自動生成索引;

SQL> set autotrac traceonly
SQL> select empno,ename,sal from emp1 e,dept2 d where e.deptno=d.deptno;

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | *成本從6減為3
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 420 | 3 (0)| 00:00:01 |
| 1 | NESTED LOOPS | | 14 | 420 | 3 (0)| 00:00:01 | *********從哈希轉為嵌套循環
| 2 | TABLE ACCESS FULL| EMP1 | 14 | 238 | 3 (0)| 00:00:01 |
|* 3 | INDEX UNIQUE SCAN| P_K | 1 | 13 | 0 (0)| 00:00:01 | *********全表掃描,轉為索引範圍


3 - access("E"."DEPTNO"="D"."DEPTNO")

Note
dynamic sampling used for this statement (level=2)

7 consistent gets

***************************************測試三(emp1與dept2建立主外鍵約束)**************************************

SQL> set autotrace off

SQL> alter table emp1 add constraint f_y foreign key(deptno) references dept2(deptno);

SQL> select owner,constraint_name from user_constraints;

OWNER CONSTRAINT_NAME
-------------------- --------------------
SCOTT P_K
SCOTT F_Y

SQL> select index_name,table_name from user_indexes where table_name=‘EMP1‘;

no rows selected

select empno,ename,sal from emp1 e,dept2 d where e.deptno=d.deptno;

| 0 | SELECT STATEMENT | | 14 | 238 | 3 (0)| 00:00:01 | ---因為測試數據量少,成本沒有變化
|* 1 | TABLE ACCESS FULL| EMP1 | 14 | 238 | 3 (0)| 00:00:01 | --對DEPT2表根本沒有查詢;
----------

1 - filter("E"."DEPTNO" IS NOT NULL) ---直接根據dept2,deptno列非空(主鍵,非空且唯一);

14 rows selected.

*******測試五、測試四的基礎上插入一條數據*******

insert into emp1(empno,ename,deptno) values(8000,‘YANG‘,null);

select empno,ename,sal from emp1 e,dept2 d where e.deptno=d.deptno;

--因為查詢是等值連接,所以,執行計劃不受影響;

但是會存在臟數據:對於外鍵約束來說,子表中的數據必須在父表中有匹配值,本次測試中,插入了Null,值沒有報錯;

insert into emp1(empno,ename,deptno) values(8100,‘YG‘,11);

ERROR at line 1:
ORA-02291: integrity constraint (SCOTT.F_Y) violated - parent key not found 外鍵還是好的;

小結:主外鍵約束,要保證數據幹凈,子表中,關聯列加上not null 約束靠譜;

alter table emp1 modify deptno not null
*
ERROR at line 1:
ORA-02296: cannot enable (SCOTT.) - null values found

SQL> delete emp1 where deptno is null;

SQL> alter table emp1 modify deptno not null;

兩表關聯查詢-創建約束,外鍵對比