兩表關聯查詢-創建約束,外鍵對比
--開啟執行計劃:
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;
兩表關聯查詢-創建約束,外鍵對比