SELECT DISTINCT S.SNAME
FROM S, SP
WHERE S.S# = SP.S# AND SP.P# = 'P2'
=> 위의 SQL문을 가지고 52개의 다른 SQL문으로 표현이 가능함
<C.J. Date 박사 An Introduction to Database Systems'>
SELECT DISTINCT S.SNAME
FROM S
WHERE S.S# IN (SELECT SP.S# FROM SP WHERE SP.P# = 'P2')';
SELECT DISTINCT S.SNAME
FROM S
WHERE EXISTS (SELECT * FROM SP WHERE SP.P# = S.S# AND SP.P# = 'P2')';
SELECT DISTINCT S.SNAME
FROM S, SP
WHERE S.S# = SP.S#
GROUP BY S.SNAME, SP.P#
HAVING SP.P# = 'P2';
SELECT DISTINCT S.SNAME
FROM S
WHERE S.S# ANY (SELECT SP.S# FROM SP WHERE SP.P# = 'P2')';
SELECT DISTINCT S.SNAME
FROM S, SP
WHERE (SELECT COUNT(*) FROM SP WHERE SP.S# = S.S# AND SP.P# = 'P2') > 0
............기타등등
=> *아래 두 쿼리는 결과는 같지만 수행속도는 다를 수 있다 *
<쿼리1>
SELECT *
FROM DEPT D
WHERE NOT EXISTS ( SELECT 'X'
FROM EMP
WHERE DEPTNO = D.DEPTNO);
Execution Plan
-------------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=6 Card=1 Bytes=23)
1 0 MERGE JOIN (ANTI) (Cost=6 Card=1 Bytes=23)
2 1 TABLE ACCESS (BY INDEX ROWID) OF 'DEPT' (TABLE) (Cost=2 Card=4 Bytes=80)
3 2 INDEX (FULL SCAN) OF 'PK_DEPT' (INDEX (UNIQUE)) (Cost=1 Card=4)
4 1 SORT (UNIQUE) (Cost=4 Card=14 Bytes=42)
5 4 TABLE ACCESS (FULL) OF 'EMP' (TABLE) (Cost=3 Card=14 Bytes=42)
<쿼리2>
SELECT D.*
FROM DEPT D, EMP E
WHERE E.DEPTNO(+) = D.DEPTNO
AND E.ROWID IS NULL;
Execution Plan
--------------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=6 Card=14 Bytes=490)
1 0 FILTER
2 1 MERGE JOIN (OUTER) (Cost=6 Card=14 Bytes=490)
3 2 TABLE ACCESS (BY INDEX ROWID) OF 'DEPT' (TABLE) (Cost=2 Card=4 Bytes=80)
4 3 INDEX (FULL SCAN) OF 'PK_DEPT' (INDEX (UNIQUE)) (Cost=1 Card=4)
5 2 SORT (JOIN) (Cost=4 Card=14 Bytes=210)
6 5 TABLE ACCESS (FULL) OF 'EMP' (TABLE) (Cost=3 Card=14 Bytes=210)
쿼리 변환의 종류
1. 서브쿼리Unnesting
2. 뷰Merging
3. 조건절Pushing
4. 조건절이행
5. 공통표현식 제거
6. Outer 조인을 Inner 조인으로 변환
7. 실체화 뷰 쿼리로 재작성
8. Star 변환
9. Outer 조인 뷰에 대한 조인 조건 Pushdown
10. OR-expansion
쿼리 변환 작동 방식