{code:SQL | title= ALL 연산자를 AND로 변환 | borderStyle=solid} ALTER SESSION SET EVENTS '10053 trace name context forever, level 1'; |
SELECT e.employee_id, e.hire_date, e.job_id, d.department_name
FROM employee e, department d
WHERE e.department_id = d.department_id
AND e.salary > ALL (2600, 4400, 13000);
ALTER SESSION SET EVENTS '10053 trace name context off';
============
Plan Table
============
Id | Operation | Name | Rows | Bytes | Cost | Time |
0 | SELECT STATEMENT | 4 | ||||
1 | MERGE JOIN | 53 | 2226 | 3 | 00:00:01 | |
2 | TABLE ACCESS BY INDEX ROWID | DEPARTMENT | 27 | 378 | 0 | |
3 | INDEX FULL SCAN | DEPT_ID_PK | 27 | 0 | ||
4 | SORT JOIN | 54 | 1512 | 3 | 00:00:01 | |
5 | TABLE ACCESS FULL | EMPLOYEE | 54 | 1512 | 2 | 00:00:01 |
* e.salary > ALL (2600, 4400 , 13000) 조건은 다음과 같이 2단계의 변환과정을 거친다
** 1단계변환 :
옵티마이져는 ALL조건을 아래와 같이변환시킨다.
e.salary > 2600 AND e.salary >4400 AND e.salary > 13000
** 2단계변환:
3개의 조건이 AND로 연결되어 있으므로 제일 큰 값인 e.salary > 13000 조건만 만족하면 나머지
2개의 조건도 만족한다. 따라서 e.salary > 13000조건만 남게 된다.
이런 기능을 Filter Subsumtion이라고 한다.
이와같이 Query Transformer는 매우 지능적이어서 All조건을 And조건으로 바꾼다음 모든 조건을 만족하는 집합인
e.SALARY > 13000집합만을 Access 하는 SQL을 만들게 되는 것이다.|
|{code:SQL|title= IN 연산자를 OR로 변환 |borderStyle=solid}
explain plan for
SELECT e.employee_id, e.first_name, e.last_name, e.email
FROM employee e, department d
WHERE e.department_id = d.department_id
AND e.department_id IN (10, 20);
select * from table(dbms_xplan.display);
---------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3 | 99 | 1 (100)| 00:00:01 |
| 1 | NESTED LOOPS | | 3 | 99 | 0 (0)| 00:00:01 |
| 2 | INLIST ITERATOR | | | | | |
| 3 | TABLE ACCESS BY INDEX ROWID| EMPLOYEE | 3 | 90 | 0 (0)| 00:00:01 |
|* 4 | INDEX RANGE SCAN | EMP_DEPARTMENT_IX | 3 | | 0 (0)| 00:00:01 |
|* 5 | INDEX UNIQUE SCAN | DEPT_ID_PK | 1 | 3 | 0 (0)| 00:00:01 |
---------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("E"."DEPARTMENT_ID"=10 OR "E"."DEPARTMENT_ID"=20)
5 - access("E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID")
filter("D"."DEPARTMENT_ID"=10 OR "D"."DEPARTMENT_ID"=20)
{code:SQL | title= ANY 연산자를 OR로 변환 | borderStyle=solid} e.salary > ANY (2600, 4400, 13000) --> (e.salary > 2600 OR e.salary > 4400 OR e.salary > 13000) {code} {code:SQL | title= NOT연산자를 제거 | borderStyle=solid} not (e.salary <> 13000 or e.department_id is null) --> e.salary = 13000 AND e.department_id IS NOT NULL {code} |