# 조건연산자는 단지 비트연산의 방식만 다르게 할 뿐이기 때문에 조건연산자의 형태에 따라 처리방법이 크게 달라지지 않는다.
SELECT * FROM SALES_SUM WHERE TIME_CD='200512'; Execution Plan --------------------------------------------- SELECT STATEMENT TABLE ACCESS (BY INDEX ROWID) OF 'SALES_SUM' BITMAP CONVERSION (TO ROWIDS) BITMAP INDEX(SINGLE VALUE) OF 'TIME_BIX'
.... WHERE TIME_CD IN ('200505','200507','200510'); Execution Plan ------------------------------------- INLIST ITERATOR TABLE ACCESS (BY INDEX ROWID) OF 'SALES_SUM' BITMAP CONVERSION (TO ROWIDS) BITMAP INDEX(SINGLE VALUE) OF 'TIME_BIX'
SELECT * FROM SALES_SUM WHERE TIME_CD BETWEEN '200505' AND '200507' Exectuion Plan ------------------------------- SELECT STATEMENT TABLE ACCESS (BY INDEX ROWID) OF 'SALES_SUM' BITMAP CONVERSION (TO ROWIDS) BITMAP INDEX (RANGE SCAN) OF 'TIME_BIX'
SELECT * FROM FROM SALES_SUM WHERE SALE_DEPT LIKE '1250%' Execution Plan ------------------------------- SELECT STATEMENT TABLE ACCESS (BY INDEX ROWID) OF 'SALES_SUM' BITMAP CONVERSION (TO ROWIDS) BITMAP INDEX (FRULL SCAN) OF 'SALE_DEPT_BIX'
SELECT * FROM SALES_SUM WHERE SALE_DEPT = '12500' AND TIME_CD ='200510'; Execution Plan ------------------------------- SELECT STATEMENT TABLE ACCESS (BY INDEX ROWID) OF 'SALES_SUM' BITMAP CONVERSION (TO ROWIDS) BITMAP AND BITMAP INDEX (SINGLE VALUE) OF 'TIME_BIX' BITMAP INDEX (SINGLE VALUE) OF 'SALE_DEPT_BIX'
SELECT * FROM SALES_SUM WHERE SALE_DEPT = '12500' AND TIME_CD BETWEEN '200510' AND '200512'; Execution Plan ------------------------------- SELECT STATEMENT TABLE ACCESS (BY INDEX ROWID) OF 'SALES_SUM' BITMAP CONVERSION (TO ROWIDS) BITMAP AND BITMAP INDEX (SINGLE VALUE) OF 'SALE_DEPT_BIX' BITMAP MERGE BITMAP INDEX (RANGE SCAN) OF 'TIME_BIX'
SELECT * FROM SALES_SUM WHERE TIME_CD = '200510' OR ITEM_CD LIKE 'ABC%' OR SALE_DEPT = 12500; Execution Plan --------------------------------------- SELECT STATEMENT TABLE ACCESS (BY INDEX ROWID) OF 'SALES_SUM' BITMAP CONVERSION (TO ROWIDS) BITMAP OR BITMAP INDEX (SINGLE VALUE) OF 'TIME_BIX' BITMAP MERGE BITMAP INDEX (RANGE SCAN) OF 'ITEM_BIX' BITMAP INDEX (SINGLE VALUE) OF 'SALE_DEPT_BIX'
SELECT * FROM SALES_SUM WHERE TIME_CD = '200512' AND SALE_DEPT <> 12500; Execution Plan ------------------------------- SELECT STATMENT TABLE ACCESS (BY INDEX ROWID) OF 'SALES_SUM' BITMAP CONVERSION (TO ROWIDS) BITMAP MINUS BITMAP INDEX (SINGLE VALUE) OF 'TIME_BIX' BITMAP INDEX (SINGLE VALUE) OF 'SALE_DEPT_BIX'
BITMAP MINUS BITMAP MINUS BITMAP INDEX (SINGLE VALUE) OF 'TIME_BIX' BITMAP INDEX (SINGLE VALUE) OF 'SALE_DEPT_BIX' BITMAP INDEX (SINGLE VALUE) OF 'SALE_DEPT_BIX' <--- NULL인경우 제거
SELECT * FROM SALES_SUM WHERE TIME_CD='200512' AND COUNTRY IS NULL; Execution Plan ---------------------------------------- SELECT STATEMENT TABLE ACCESS (BY INDEX ROWID) OF 'SALES_SUM' BITMAP CONVERSION (TO ROWIDS) BITMAP AND BITMAP INDEX (SINGLE VALUE) OF 'TIME_BIX' BITMAP INDEX (SINGLE VALUE) OF 'COUNTRY_BIX'
SELECT * FROM SALES_SUM WHERE ITEM_CD IN (SELECT ITEM_CD FROM ITEM_T WHERE CATEGORY_CD = 'ABC' ); Execution Plan ------------------------------------ SELECT STATEMENT TABLE ACCESS (BY INDEX ROWID) OF 'SALES_SUM' NESTED LOOPS SORT (UNIQUE) <----- 서브 쿼리 TABLE ACCESS (BY INDEX ROWID) OF 'ITEM_T' INDEX (RANGE SCAN) OF 'ITEM_IDX2' (NON-UNIQUE) BITMAP CONVERSION (TO ROWIDS) BITMAP INDEX (SINGLE VALUE) OF 'ITEM_BIX' <-- 제공 받은 값으로 비트맵 인덱스
SELECT /*+ STAR_TRANSFORMATION */ I.ITEM_CD, SUM(S.AMOUNT) SAL_AMOUNTS FROM SALES_SUM S,ITEMS I,COUNTRYS C WHERE S.ITEM_CD = I.ITEM_CD AND S.COUNTRY = C.COUNTRY_CD AND I.CATEGORY_TYPE = 'Clothes' AND C.AREA='EUROPE' GROUP BY I.ITEM_CD; Execution Plan -------------------------------- SELECT STATMENT Optimizer=ALL_ROWS SORT GROUP BY HASH JOIN HASH JOIN <-- 엑세스한 팩트 테이블과 디멘전 테이블 조인 TABLE ACCESS (BY INDEX ROWID) OF 'SALES_SUM' <-- 비트맵들을 결합하여 액세스 BITMAP CONVERSION (TO ROWIDS) BITMAP AND BITMAP AND BITMAP MERGE <-- ITEMS 서브쿼리로 팩트 테입ㄹ의 비트맵 액세스 BITMAP KEY ITERATION TABLE ACCESS (FULL) OF 'ITEMS' BITMAP INDEX (RANGE SCAN) OF 'ITEM_BIX' BITMAP MERGE <-- COUNTRY 서브쿼리로 팩트 테이블의 비트맵 액세스 BITMAP KEY ITERATION TABLE ACCESS (FULL) OF 'COUNTRYS' BITMAP INDEX (RANGE SCAN) OF 'COUNTRY_BIX'
SELECT /*+ INDEX_COMBINE (SALES) */ * FROM SALES WHERE ITEM_CD = 'PA100' AND PRICE >= 100000; Execution Plan ---------------------------------------- SELECT STATEMENT TABLE ACCESS (BY INDEX ROWID) OF 'SALES' BITMAP CONVERSION (TO ROWIDS) BITMAP AND BITMAP INDEX (SINGLE VALUE) OF 'ITEM_BIX' BITMAP CONVERSION (FROM ROWIDS) <- BTREE를 비트맵으로 전환 SORT (ORDER BY) INDEX (RANGE SCAN) OF 'PRICE_IDX' (NON-UNIQUE)
SELECT LPAD(' ',2* (LEVEL -1__ || ename, empno, sal,mgr, SYS_CONNECT_BY_PATH(last_name,'/') "Path" FROM emp WHERE job='CLERK' CONNECT BY mgr= PRIOR empno START WITH empno= :b1; Execution Plan ------------------------------------- SELECT STATEMENT FILETER --- 3 where절 job='clerk' CONNECT BY (WITH FILTERNING) NESTED LOOPS --- 1 start with 에서 정한 초기 조건 INDEX (UNIQUE SCAN) OF 'PK_EMP' (UNIQUE) TABLE ACCESS (BY USER ROWID) OF 'EMP NESTED LOOPS ---2 connect by 절의 prior 절뒤쪽을 가져와서 상대 컬럼을 조인비교 BUFFER (SORT) CONNECT BY PUMY TABLE ACCESS (BY INDEX ROWID) OF 'EMP' INDEX (RANGE SCAN) OF 'MGR_IDX' (UNIQUE)
UPDATE emp e SET sal = (SELECT AVG(sal) * 1.2 FROM bouns b WHERE b.empno=e.empno AND b.pay_date between :b1 and :b2) WHERE deptno IN (SELECT deptno FROM dept WHERE loc='BOSTON'); Execution Plan ------------------------- UPDATE STATEMENT UPDATE OF 'EMP' TABLE ACCESS (BY INDEX ROWID) OF 'EMP' NESTED LOOPS TABLE ACCESS (BY INDEX ROWID) OF 'DEPT' --- 서브쿼리를 수행 하여 메인쿼리와 조인 INDEX (RANGE SCAN) OF 'LOC_IDX' (NON-UNIQUE) INDEX (RANGE SCAN) OF 'EMP_DEPTNO_IDX' (NON-UNIQUE) SORT (AGGREGATE) TABLE ACCESS (BY INDEX ROWID) OF 'BONUS' -- SET 절의 스칼라 쿼리 수행 INDEX (RANGE SCAN) OF 'BONUS_PK' (UNIQUE)
===나) 뷰의 UPDATE
CREATE OR REPLACE VIEW EMP_DEPT_VIEW AS SELECT X.EMPNO, X.ENAME, X.JOB, X.SAL, Y.LOC, Y.DNAME FROM EMP X, DEPT Y WHERE X.DEPTNO = Y.DEPTNO; UPDATE EMP_DEPT_VIEW E SET SAL= DECODE(DNAME,'SALES',1.2,1,1) * SAL WHERE LOC LIKE 'AB%'; Execution Plan ------------------------------------- UPDATE STATEMENT UPDATE OF 'EMP' HASH JOIN TABLE ACCESS (BY INDEX ROWID) OF 'DEPT' INDEX (RANGE SCAN) OF 'LOC_IDX' (NON-UNIQUE) TABLE ACCESS (FULL) OF 'EMP'
서브쿼리 팩토링 실행계획
WITH total_sal AS (SELECT D.deptno, D.loc, E.job, sum(E.sal) tot_sal FROM emp E, dept D WHERE E.deptno=D.deptno AND E.hiredate > :b1 GROUP BY D.deptno, D.loc, E.job) SELECT e.empno, e.name, e.sal, e.sal/t.tot_sal sal_percent FROM emp e,total_sal t WHERE e.deptno = t.deptno AND e.sal > (SELECT max(tot_sal) FROM total_sal WHERE job='CLERK'); Execution Plan ---------------------- SELECT STATEMENT RECURSIVE EXECUTION OF 'SYS_LE_2_0' --- WITH 절의 쿼리 수행 TEMP TABLE TRANSFORMATION TABLE ACCESS (BY INDEX ROWID) OF OF 'EMP' NESTED LOOPS VIEW TABLE ACCESS (FULL) OF 'SYS_TEMP_0FD9D6616_165207A' INDEX (RANGE SCAN) OF 'EMP_DEPTNO_IDX' (NON-UNIQUE) SORT (AGGREGATE) VIEW TABLE ACCESS (FULL) OF 'SYS_TEMP_0FD9D6616_165207A'
DELETE FROM (SELECT * FROM EMP WHERE JOB='CLERK' AND comm > 10000 AND deptno IN (SELECT deptno FROM dept WHERE loc='BOSTOM')); Execution Plan ----------------------------------------- DELETE STATEMENT DELETE OF 'EMP' NESTED LOOPS TABLE ACCESS (BY INDEX ROWID) OF 'EMP' INDEX (UNIQUE SCAN) OF 'PK_EMP' (UNIQUE) TABLE ACCESS (BY INDEX ROWID) OF 'DEPT' INDEX (UNIQUE SCAN) OF 'PK_DEPT' (UNIQUE)
INSERT ALL WHEN ORDER_TOTAL < 1000000 THEN INTO SMALL_ORDERS WHEN ORDER_TOTAL > 1000000 AND ORDER_TOTAL < 2000000 THEN INTO MEDIUM_ORDERS WHEN ORDER-TOTAL > 2000000 THEN INTO LARGE_ORDERS SELECT ORDER_ID,ORDER_TOTAL,SALES_REP_ID,CUSTOMER_ID FROM ORDERS; ------------------ INSERT STATEMENT MULTI-TABLE INSERT INTO OF 'SMALL_ORDERS' INTO OF 'MEDIUM_ORDERS' INTO OF 'LARGE_ORDERS' TABLE ACCESS (FULL) OF 'ORDERS'
SELECT department_id,manager_id FROM employees GROUP BY department_id,manager_id HAVING (department_id, manager_id) IN (SELECT e.deptno, e.mgr FROM emp e,dept d WHERE e.deptno = d.deptno AND d.oc='BOSTON'); Execution Plan ------------------------------- SELECT STATEMENT FILTER SORT (GROUP BY) TABLE ACCESS (FULL) OF 'EMPLOYEES' NESTED LOOPS TABLE ACCESS (BY INDEX ROWID) OF 'DEPT' INDEX (RANGE SCAN) OF 'LOC_IDX' (NON-UNIQUE) AND-EQUAL INDEX (RANGE SCAN) OF 'EMP_MGR_IDX' (NON-UNIQUE) INDEX (RANGE SCAN) OF 'EMP_DEPTNO_IDX' (NON-UNIQUE)
SELECT co.country_region,co.country_subregion, SUM*s.amount_sold) "Revenue", GROUP_ID() g FROM sales s,customers c, countries co WHERE s.cust_id=c.cust_id AND c.country_id=co.country_id AND s.time_id= :b1 AND co.country_region IN ('Americas','Europe') GROUP BY ROLLUP (co.country_region, co.country_subregion); Execution Plan ----------------------------- SELECT STATEMENT SORT (GROUP BY ROLLUP) NESTED LOOPS NESTED LOOPS PARTITION RANGE (SINGLE) TABLE ACCESS (BY LOCAL INDEX ROWID) OF 'SALES' BITMAP CONVERSION (TO ROWIDS) BITMAP INDEX (SINGLE VALUE) OF 'SALES_TIME_BIX' TABLE ACCESS (BY INDEX ROWID) OF 'CUSTOMERS' INDEX (UNIQUE SCAN) OF 'CUSTOMERS_PK' (UNIQUE) INDEX (UNIQUE SCAN) OF 'COUNTRY_C_ID_PK' (UNIQUE)
MERGE INTO bonuses D USING ( SELECT employee_id, salary, department_id FROM employees WHERE department_id=80) S ON (D.employee_id = S.employee_id) WHEN MATCHED THEN UPDATE SET D.bonus = D.bonus + S.salary * .01 DELETE WHERE (S.salary > 8000) WHEN NOT MATCHED THEN INSERT (D.employee_id, D.bonus) VALUES (S.employee_id, S.salary * 0.1); Execution Plan ------------------------------------- MERGE STATEMENT MERGE OF 'BONUSES' VIEW NESTED LOOPS (OUTER) TABLE ACCESS (BY INDEX ROWID) OF 'EMPLOYEES' INDEX (RANGE SCAN) OF 'EMPLOYEE_X1' (NON-UNIQUE) TABLE ACCESS (BY INDEX ROWID) OF 'BONUSES' INDEX (RANGE SCAN) OF 'BONUSES_X1' (NON-UNIQUE)