Microsoft PowerPoint - Oracle Data Join Method.pptx [읽기 전용]

Similar documents
Microsoft PowerPoint - Oracle Data Access Pattern.ppt

Jerry Held


SQL Tuning Business Development DB

歯sql_tuning2

다양한 예제로 쉽게 배우는 오라클 SQL 과 PL/SQL

단답형 (26 회기출문제 ) 1. 아래와같은테이블이있을때아래의 SQL 결과에대해서 Oracle, SQL Server 순서로적으시오 TAB1 COL1 CHAR(10) COL2 CHAR(10) INSERT INTO TAB1 VALUES ('1',''); INSERT INT

Microsoft Word - SQL튜닝_실습교재_.doc

객관식 1. 아래의쿼리를만족하는결과를가장잘설명한것은? SELECT A.* FROM HR.EMPLOYEES A, HR.EMPLOYEES B WHERE 1=1 AND A.MANAGER_ID = B.EMPLOYEE_ID AND B.SALARY >= ANY A.SALARY;

13주-14주proc.PDF

다양한 예제로 쉽게 배우는 오라클 SQL 과 PL/SQL

@OneToOne(cascade = = "addr_id") private Addr addr; public Emp(String ename, Addr addr) { this.ename = ename; this.a

결과보고서

WINDOW FUNCTION 의이해와활용방법 엑셈컨설팅본부 / DB 컨설팅팀정동기 개요 Window Function 이란행과행간의관계를쉽게정의할수있도록만든함수이다. 윈도우함수를활용하면복잡한 SQL 들을하나의 SQL 문장으로변경할수있으며반복적으로 ACCESS 하는비효율역

ePapyrus PDF Document

0. Intro ORACLE 社 Oracle, My SQL, Exadata IBM 社 DB2, Informix SAP 社 ASE, IQ, ASA Microsoft 社 SQL Server Teradata 社 Teradata 공통점은? Altibase 社 Altibase

목차 BUG 문법에맞지않는질의문수행시, 에러메시지에질의문의일부만보여주는문제를수정합니다... 3 BUG ROUND, TRUNC 함수에서 DATE 포맷 IW 를추가지원합니다... 5 BUG ROLLUP/CUBE 절을포함하는질의는 SUBQUE

RDB개요.ppt

Result Cache 동작원리및활용방안 엑셈컨설팅본부 /DB 컨설팅팀김철환 개요 ORACLE DBMS 를사용하는시스템에서 QUERY 성능은무엇보다중요한요소중하나이며그 성능과직접적인관련이있는것이 I/O 이다. 많은건수를 ACCESS 해야만원하는결과값을얻을수있는 QUER

SQL Server 에서 SQL 튜닝시알아야할힌트와사용 방법 엑셈컨설팅본부 /DB 컨설팅팀박성호 Optimizer 가 SQL 을해석할때항상최적의실행계획을생성하지는못한다. 복잡한 SQL 일수록최적의실행계획을생성하기위해고려해야할대상 (Table, Index 가많은경우 )

´ÙÁß Row °á°ú¸¦ ´ÜÀÏÇàÀ¸·Î Äĸ¶·Î ºÐ¸®ÇØ Ãâ·ÂÇÏ´Â ¹æ¹ý

Bind Peeking 한계에따른 Adaptive Cursor Sharing 등장 엑셈컨설팅본부 /DB 컨설팅팀김철환 Bind Peeking 의한계 SQL 이최초실행되면 3 단계의과정을거치게되는데 Parsing 단계를거쳐 Execute 하고 Fetch 의과정을통해데이터

InsertColumnNonNullableError(#colName) 에해당하는메시지출력 존재하지않는컬럼에값을삽입하려고할경우, InsertColumnExistenceError(#colName) 에해당하는메시지출력 실행결과가 primary key 제약에위배된다면, Ins

FlashBackt.ppt

MS-SQL SERVER 대비 기능

PowerPoint 프레젠테이션

예제소스는 에서다운로드하여사용하거나툴바의 [ 새쿼리 ]( 에아래의소스를입력한다. 입력후에는앞으로실습을위해서저장해둔다. -- 실습에필요한 Madang DB 와 COMPANY DB 를모두생성한다. -- 데이터베이스생성 US

I T C o t e n s P r o v i d e r h t t p : / / w w w. h a n b i t b o o k. c o. k r

untitled

5장 SQL 언어 Part II

슬라이드 1

DB 성능고도화핵심원리 비투엔컨설팅 수석컨설턴트 조시형

객관식 1번풀이사전지식 * 비교연산자 ANY ( 서브쿼리 ) - 서브쿼리의결과에존재하는어느하나의값이라도만족하는조건을의미. 비교연산자로 " > " 를사용했다면메인쿼리는서브쿼리의값들중어떤값이라도만족하면되므로서브쿼리의결과의최소값보다큰모든건이조건을만족 - SOME 과동일 1번

다양한 예제로 쉽게 배우는 오라클 SQL 과 PL/SQL

강의 개요

SQL 실행계획을 이용한 패턴튜닝_ _최종.ppt [호환 모드]

DBMS & SQL Server Installation Database Laboratory

SQL Tuning Business Development DB SQL - -SQL -SQL

3 S Q L A n t i p a t t e r n s Trees/intro/parent.sql CREATE TABLE Comments ( comment_id SERIAL PRIMARY KEY, parent_id BIGINT UNSIGNED, comment TEXT

Microsoft PowerPoint - 10Àå.ppt

ORACLE-SQL

Oracle 10g SQL , PL/SQL 튜닝

ORACLE EXADATA HCC 압축방식이해하기 엑셈컨설팅본부 /DB 컨설팅팀김철환 개요 시간이지나면서데이터는급속하게증가하고있다. 데이터가증가함에따라 DBMS 에서관리되어지는정보도급속하게증가하고있다. 이로인해저장공간의부족으로하드웨어비용의증가와데이터처리성능에많은문제점들

ORANGE FOR ORACLE V4.0 INSTALLATION GUIDE (Online Upgrade) ORANGE CONFIGURATION ADMIN O

PowerPoint 프레젠테이션

NLJ BATCH 과부분범위처리 엑셈컨설팅본부 / DB 컨설팅팀오수영 개요 오라클은새로운버전이출시될때마다한층업그레이드된기능들이추가된다. 이기능들은사용자에게편리함을제공함은물론이고, 기존의기능들이성능적으로업그레이드되어보다강력해지기도한다. 그러나때로는새롭게추가된기능으로인해,

Microsoft PowerPoint - 1_3_DBA_SQL_tuning

Oracle Database 10g: Self-Managing Database DB TSC

TECHNICAL WHITE PAPER Tibero Optimizer SQL Execution Plan October 2012

歯PLSQL10.PDF

10.ppt

초보자를 위한 분산 캐시 활용 전략

다양한 예제로 쉽게 배우는 오라클 SQL 과 PL/SQL

< 그림 1> Nested Loop Join - 이너테이블에인덱스가있을경우 < 그림 2> Nested Loop Join - 이너테이블에인덱스가없는경우 간은느리다. 즉첫번째로우를받을준비가되어있는단계까지를실행시간으로볼때실행시간은빠르나 Fetch 시간은느리다. NLJ는메모리

강의 개요

Microsoft Word - [Unioneinc] 특정컬럼의 통계정보 갱신_ _ldh.doc

ETL_project_best_practice1.ppt

빅데이터 분산 컴퓨팅 -6

Spring Boot/JDBC JdbcTemplate/CRUD 예제

I. - II. DW ETT Best Practice

제목 레이아웃

개발자를 위한 오라클 SQL 튜닝

PowerPoint Presentation

Microsoft PowerPoint - 27.pptx

빅데이터분산컴퓨팅-5-수정

GROUPING SETS 등의새로운리포팅기능 - WINDOW FUNCTION 같은새로운개념의분석기능들 가. 일반집합연산자 현재사용하는 SQL 의많은기능이관계형데이터베이스의이론을수립한 E.F.Codd 박사의논문에언급이되어있다. 논문에언급된 8 가지관계형대수는다시각각 4

Query Process 단계처리내용 Parse 단계 Syntax, Security, Semantics의체크및Simple transformation 을수행한다 < 표 2>. Query Rewrite 단계서브질의와뷰의병합을수행하고, OR Expansion 작업을수행한다.

BMP 파일 처리

SQL초보에서Schema Object까지

USER GUIDE

MySQL-.. 1

PostgreSQL 2 Uniersity of California at Berkeley ( ) 에서개발된관계형데이터베이스서버인 Ingres 가시초 ( 후에 Computer Associates 에인수됨 ) 1

목차 BUG offline replicator 에서유효하지않은로그를읽을경우비정상종료할수있다... 3 BUG 각 partition 이서로다른 tablespace 를가지고, column type 이 CLOB 이며, 해당 table 을 truncate

대량의 DML 작업에대한성능개선방안 엑셈컨설팅본부 /DB 컨설팅팀박준연 개요 대량의데이터를변경해야하는작업은그자체만으로도큰부담으로다가온다. 하지만변경작업자체에만국한되는것이아니라변경되기전데이터와변경이후데이터를각각저장관리해야하는메커니즘이라면성능을개선해야하는입장에서는더욱큰부담

Microsoft Word - PLSQL.doc

목차 BUG DEQUEUE 의 WAIT TIME 이 1 초미만인경우, 설정한시간만큼대기하지않는문제가있습니다... 3 BUG [qp-select-pvo] group by 표현식에있는컬럼을참조하는집합연산이존재하지않으면결괏값오류가발생할수있습니다... 4

ALTIBASE HDB Patch Notes

Microsoft PowerPoint _TechNet_SQL Server 2005.ppt [호환 모드]

다양한 예제로 쉽게 배우는 오라클 SQL 과 PL/SQL

SQL PLAN MANAGEMENT 활용 엑셈컨설팅본부 /DB 컨설팅팀장정민 개요 오라클은비롯한많은관계형 DBMS 에서는사용자의 SQL 질의를효율적으로처리하기위해옵티마이저를사용하고있다. 옵티마이저는유저가수행하는 SQL 을받아실행계획을생성하고, 실제 SQL 은이실행계획을

Frama-C/JESSIS 사용법 소개

PowerPoint Presentation

목 차

TITLE

62

SQL

Oracle Magazine 2003 summer

Partition Table

PowerPoint Presentation

PowerPoint 프레젠테이션

Tablespace On-Offline 테이블스페이스 온라인/오프라인

PowerPoint Template

[ 목차 ] 5.1 데이터베이스프로그래밍개념 5.2 T-SQL T-SQL 문법 5.3 JAVA 프로그래밍 2

<C1A62038B0AD20B0ADC0C7B3EBC6AE2E687770>

1. SQL 문의종류 2 DDL (Data Definition Language) : 데이터와그구조를정의 SQL문 CREATE DROP ALTER 내용데이터베이스객체를생성데이터베이스객체를삭제기존에존재하는데이터베이스객체를다시정의하는역할 DML (Data Manipulati

PowerPoint Presentation

Observational Determinism for Concurrent Program Security

Microsoft Word - 04_EXCEPTION.doc

ALTIBASE HDB Patch Notes

Slide 1

Transcription:

Special Key Note Oracle Data Join Method ( 주 ) 오픈메이드컨설팅 오동규수석컨설턴트 1

What is Join? JOIN is Multiply. 2

Why is the Join Method so important? 잘못사용하면큰재앙이따른다.( 위의그림처럼 ) 두개의집합을연결할수있는유일한수단. Join Method 는모든 DBMS 가대동소이. 3

Learning Join Method - Any Benefit? Learning Join Before Learning Join After Execution Plan 이눈에들어옴. 비로소 SQL 튜닝이가능해짐. 적절한 Join Method 를적소에사용하는것이 SQL 튜닝임. Data Access Pettern 과밀접한관련이있음. 4

Oracle Data Join Method Nested Loop Join Sort Merge Join Hash Join Outer Join Using SubQuery Join Method 에따라용도가다르다. 5

Oracle Data Join Method Contents Nested Loop Join Sort Merge Join Hash Join Cartesian Join ( 혹은 Cross Join) Sub Query (In, Any, All, Exists, Subquery Factoring) Semi Join (Nested Loop, Sort Merge, Hash, Hash Join Right) Anti Join (Nested Loop, Sort Merge, Hash, Hash Join Right) Index Join Outer Join (Full,Nested Loop, Sort Merge, Hash, Hash Join Right) Partition Outer Join Star Query Transformation 6

Nested Loop Join > 특징 > 적용 > Hint 먼저수행되는집합 (Driving) 의처리범위가전체일량을좌우 먼저수행되는집합 (Driving) 이상수로바뀌어후행테이블에공급된다. 후행테이블은계속 Loop 를돌면서 Driving 테이블의상수공급이끝날때까지조인한다. Single Block I/O Random Access 발생 ( 테이블 access 가필요한경우 ) 소량의데이터처리 (OnLine) 는유리 대량의데이터처리 (Batch) 는큰부하발생 ( 페이징처리된 SQL 은예외 ) OLTP 시스템 처리해야하는범위가소량인경우 (10 만건미만 ) 부분범위 ( 페이징 ) 처리시 select /*+ use_nl(a b) */ a.empno, a.ename, b.dname from emp a, dept b where a.deptno = b.deptno ; 7

Nested Loop Join -Concept > Full Unique 인덱스 layout : dept(deptno) pk select a.empno, a.ename, b.dname from emp a, dept b where a.deptno = b.deptno ; EMP 테이블 PK_DEPT 인덱스 DEPT 테이블 EMPNO ENAME DEPTNO. DEPTNO DNAME LOC 7782 CLARK 10. 7788 SCOTT 20. 7902 FORD 20. 7839 KING 10.. 10 20 30 40 10 ACCOUNTING NEW YORK 30 SALES CHICAGO 20 RESEARCH DALLAS 40 OPERATIONS BOSTON Full Table Scan Multi Block I/O 8

Nested Loop Join - 예제 > Full Unique 실행계획 인덱스 layout : dept(deptno) p pk select a.empno, a.ename, b.dname from emp a, dept b where a.deptno = b.deptno ; ----------------------------------------------------------------------------------------------------------- Id Operation Name Starts E-Rows A-Rows A-Time Buffers Reads ----------------------------------------------------------------------------------------------------------- 1 NESTED LOOPS 1 1 13 00:00:00.03 03 23 8 2 TABLE ACCESS FULL EMP 1 1 14 00:00:00.02 8 6 3 TABLE ACCESS BY INDEX ROWID DEPT 14 1 13 00:00:00.01 15 2 * 4 INDEX UNIQUE SCAN PK_DEPT 14 1 13 00:00:00.01 2 1 ----------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 4 - access("a"."deptno"="b"."deptno") 9

Nested Loop Join -Concept >Full Range scan 인덱스 layout : emp(deptno) 생성 dept(deptno) pk select a.empno, a.ename, b.dname from emp a, dept b where a.deptno = b.deptno ; EMP 테이블 Full Table Scan Multi Block I/O EMPNO ENAME DEPTNO. 7844 TURNER 30. DEPT 테이블 DEPTNO DNAME LOC 10 ACCOUNTING NEW YORK 30 SALES CHICAGO 20 RESEARCH DALLAS... EMP.DEPT 인덱스 10 20 30. 7782 CLARK 10. 7788 SCOTT 20. 7902 FORD 20. 7839 KING 10. 10

Nested Loop Join - 예제 > Full Range 실행계획 인덱스 layout : emp(deptno) 생성 dept(deptno) pk select a.empno, a.ename, b.dname from emp a, dept b where a.deptno = b.deptno ; ------------------------------------------------------------------------------------------------------------ Id Operation Name Starts E-Rows A-Rows A-Time Buffers Reads ------------------------------------------------------------------------------------------------------------ 1 TABLE ACCESS BY INDEX ROWID EMP 1 1 13 00:00:00.01 15 5 2 NESTED LOOPS 1 1 18 00:00:00.17 11 5 3 TABLE ACCESS FULL DEPT 1 1 4 00:00:00.01 01 8 5 * 4 INDEX RANGE SCAN IX_EMP_N2 4 2 13 00:00:00.01 3 0 ------------------------------------------------------------------------------------------------------------ Predicate Information (identified by operation id): --------------------------------------------------- 4 - access("a"."deptno"="b"."deptno") 11

Nested Loop Join -Concept >Range Range 인덱스 layout : dept(deptno) PK emp(deptno) select a.empno, a.ename, b.dname from emp a, dept b where a.deptno = b.deptno and b.deptno BETWEEN 10 AND 20; EMP 테이블 EMPNO ENAME DEPTNO. PK_DEPT DEPT 테이블 EMP.DEPT 7782 CLARK 10 인덱스 인덱스 DEPTNO DNAME LOC 7782 CLARK 10. 10 20 10 ACCOUNTING NEW YORK 30 SALES CHICAGO 10 20 7788 SCOTT 20. 30 20 RESEARCH DALLAS 30 40 40 OPERATIONS BOSTON 40 7902 FORD 20. 7839 KING 10. 12

Nested Loop Join - 예제 > Range-Rane 실행계획 인덱스 layout : dept(deptno) PK emp(deptno) select a.empno, a.ename, b.dname from emp a, dept b where a.deptno = b.deptno and b.deptno BETWEEN 10 AND 20; ----------------------------------------------------------------------------------------------------- Id Operation Name Starts E-Rows A-Rows A-Time Buffers ----------------------------------------------------------------------------------------------------- 1 TABLE ACCESS BY INDEX ROWID EMP 1 1 7 00:00:00.01 10 2 NESTED LOOPS 1 1 10 00:00:00.01 7 3 TABLE ACCESS BY INDEX ROWID DEPT 1 2 2 00:00:00.01 4 * 4 INDEX RANGE SCAN PK_DEPT 1 2 2 00:00:00.01 2 * 5 INDEX RANGE SCAN IX_EMP_N2 2 1 7 00:00:00.01 3 ----------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 4 - access("b"."deptno">=10 AND "B"."DEPTNO"<=20) 5 - access("a"."deptno"="b"."deptno") filter(("a"."deptno"<=20 AND "A"."DEPTNO">=10)) 13

Nested Loop Join -Concept > Unique Unique 인덱스 layout : dept(deptno) PK emp(empno) PK select a.empno, a.ename, b.dname from emp a, dept b where a.deptno = b.deptno and a.empno = 7839; EMPNO 인덱스 EMP 테이블 EMPNO ENAME DEPTNO. PK_DEPT 인덱스 DEPT 테이블 인덱스 DEPTNO DNAME LOC 7839 KING 10. 10 20 30 10 ACCOUNTING NEW YORK 30 SALES CHICAGO 20 RESEARCH DALLAS 7782 CLARK 10. 40 40 OPERATIONS BOSTON 7788 SCOTT 20. 7839 7902 FORD 20. 14

Nested Loop Join - 예제 > Unique-Unique 실행계획 인덱스 layout : dept(deptno) PK emp(empno) PK select a.empno, a.ename, b.dname from emp a, dept b where a.deptno = b.deptno and a.empno = 7839; -------------------------------------------------------------------------------------------------- Id Operation Name Starts E-Rows A-Rows A-Time Buffers -------------------------------------------------------------------------------------------------- 1 NESTED LOOPS 1 1 1 00:00:00.01 4 2 TABLE ACCESS BY INDEX ROWID EMP 1 1 1 00:00:00.01 2 * 3 INDEX UNIQUE SCAN PK_EMP 1 1 1 00:00:00.01 1 4 TABLE ACCESS BY INDEX ROWID DEPT 1 4 1 00:00:00.01 2 * 5 INDEX UNIQUE SCAN PK_DEPT 1 1 1 00:00:00.01 1 -------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 3 - access("a"."empno"=7839) 5 - access("a"."deptno"="b"."deptno") 15

Sort Merge Join > 특징 조인되는컬럼에인덱스존재유무가문제되지않음 정렬 (Sort) 을대신할인덱스가존재할경우부하감소 > 적용 > Hint 처리량이많은전체범위에주로사용 (Batch) 부분범위처리 ( 페이징처리 ) 가안되며 Nested Loop Join 의 Random 액세스가크게부담이되는경우양쪽테이블을 full table scan 을사용함으로서부하를경감시킬수있음. 조인된컬럼을기준으로결과집합을 sort 해야될경우최적의적용조건임. /*+ use_merge(a b) */ select /*+ use_merge(a b) */ a.empno, a.ename, b.dname from emp a, dept b where a.deptno = b.deptno Order by b.deptno ; 16

Sort Merge Join -Concept >Range Merge Range select /*+ use_merge(a b) */ a.dname, b.empno, b.ename from dept a, big_emp b where a.deptno = b.deptno and a.deptno between 10 and 20 and b.hiredate between to_ date('20020101', 'yyyymmdd') and to_date('20021231', 'yyyymmdd') order by b.deptno ; PK_DEPT DEPT BIG_EMP IX_BIG_EMP_N3 S O R T Merge S O R T 결과집합 RETURN 17

Sort Merge Join 예제1 > 실행계획 select /*+ use_merge(a b) */ a.dname, b.empno, b.ename from dept a, big_emp b where a.deptno = b.deptno and a.deptno between 10 and 20 and b.hiredate between to_date('20020101', 'yyyymmdd') and to_date('20021231', 'yyyymmdd') order by b.deptno ; ----------------------------------------------------------------------------------------------------------- Id Operation Name Starts A-Rows A-Time Buffers Used-Mem ----------------------------------------------------------------------------------------------------------- 1 MERGE JOIN 1 2048 00:00:00.03 439 2 SORT JOIN 1 2 00:00:00.01 01 2 2048 (0) 3 TABLE ACCESS BY INDEX ROWID DEPT 1 2 00:00:00.01 2 * 4 INDEX RANGE SCAN PK_DEPT 1 2 00:00:00.01 1 * 5 SORT JOIN 2 2048 00:00:00.03 437 158K (0) 6 TABLE ACCESS BY INDEX ROWID BIG_EMP 1 4096 00:00:00.02 437 * 7 INDEX RANGE SCAN IX_BIG_EMP_N3 1 4096 00:00:00.01 01 13 ----------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 4 - access("a"."deptno">=10 AND "A"."DEPTNO"<=20) 5 - access("b"."deptno"=to_number("a"."deptno")) filter("b"."deptno"=to_number("a"."deptno")) 7 - access("b"."hiredate">=to_date(' 2002-01-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "B"."HIREDATE"<=TO_DATE(' 2002-12- 31 00:00:00', 'syyyy-mm-dd hh24:mi:ss')) 18

Sort Merge Join -Concept >Full Merge Full select /*+ use_merge(a b) */ a.dname, b.empno, b.ename from dept a, big_emp b where a.deptno = b.deptno and b.sal > 1000 ; DEPT BIG_EMP S O R T Merge S O R T 결과집합 RETURN 19

Sort Merge Join 예제2 > 실행계획 select /*+ use_merge(a b) */ a.dname, b.empno, b.ename from dept a, big g_ emp pb where a.deptno = b.deptno and b.sal > 1000 ; ------------------------------------------------------------------------------------------- Id Operation Name Starts A-Rows A-Time Buffers Used-Mem ------------------------------------------------------------------------------------------- 1 MERGE JOIN 1 20480 00:00:00.07 07 251 2 SORT JOIN 1 5 00:00:00.01 3 2048 (0) 3 TABLE ACCESS FULL DEPT 1 5 00:00:00.01 3 * 4 SORT JOIN 5 20480 00:00:00.05 248 865K (0) * 5 TABLE ACCESS FULL BIG_EMP 1 24576 00:00:00.01 248 ------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 4 - access("b"."deptno"=to_number("a"."deptno")) filter("b"."deptno"=to TO_NUMBER( NUMBER("A"."DEPTNO")) 5 - filter("b"."sal">1000) 20

Hash Join > 특징 > 적용 > Hint 먼저처리되는집합 (Driving) 이소량일때성능극대화됨. 연산자의제약 : 조인조건이 = (Equal) 조건에서만가능 메모리내에서수행시빠른속도보장 메모리사용량 (HASH_AREA_SIZE AREA SIZE ) 과 CPU 사용량이많음. Nested Loop 에서의 Random 액세스가부담스러울때 Sort Merge Join 에서의정렬 (Sort) 작업이부담스러울때 초대용량테이블을조인해야되는경우 ( 몇억건이상 ) 대량의데이터처리, Batch 처리, 테이블 FULL 스캔시유리 Parallel Query 와함께사용시수행속도극대화 온라인프로그램에함부로적용하지말것. /*+ use_hash(a b) */ SELECT /*+ use_hash(a b) */ a.empno, a.ename, b.dname FROM emp a, dept b WHERE a.deptno = b.deptno ; 21

Hash Join - Concept >Range Hash Range 용어정리 Build Input 테이블 : Driving 테이블을의미함 Probe 테이블 : 후행테이블을의미함 Hash Table : Build Input 테이블을담아두는임시적인공간을의미함이공간은대부분메모리영역이며부족할경우 Disk 를사용하게됨으로성능이저하됨. select /*+ use_hash(a b) */ a.dname, b.empno, b.ename from dept a, big_emp b where e a.deptno = b.deptno and a.deptno between 10 and 20 and b.hiredate between to_date('20020101', 'yyyymmdd') and to_date('20021231', 'yyyymmdd') ; PK_DEPT DEPT BIG_EMP IX_BIG_EMP_N3 HASH TABLE BUILD INPUT TABLE PROBE TABLE 22

Hash Join 예제1 > 실행계획 select /*+ use_hash(a b) */ a.dname, b.empno, b.ename from dept a, big_emp b where a.deptno = b.deptno and a.deptno between 10 and 20 and b.hiredate between to_date('20020101', 'yyyymmdd') and to_date('20021231', 'yyyymmdd') ; ---------------------------------------------------------------------------------------------------------- Id Operation Name Starts A-Rows A-Time Buffers Used-Mem ---------------------------------------------------------------------------------------------------------- * 1 HASH JOIN 1 2048 00:00:00.04 688 435K (0) 2 TABLE ACCESS BY INDEX ROWID DEPT 1 2 00:00:00.01 2 * 3 INDEX RANGE SCAN PK_DEPT 1 2 00:00:00.01 01 1 4 TABLE ACCESS BY INDEX ROWID BIG_EMP 1 4096 00:00:00.04 686 * 5 INDEX RANGE SCAN IX_BIG_EMP_N3 1 4096 00:00:00.01 150 ---------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - access("b"."deptno"=to_number("a"."deptno")) 3 - access("a"."deptno">='10' AND "A"."DEPTNO"<='20') 5 - access("b"."hiredate">=to_date(' 2002-01-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "B"."HIREDATE"<=TO_DATE(' 2002-12-31 00:00:00', 'syyyy-mm-dd hh24:mi:ss')) 23

Hash Join - Concept >Full Hash Full(Probe) SELECT /*+ use_hash(a b) */ a.empno, a.ename, b.dname FROM emp a, dept b WHERE a.deptno = b.deptno ; DEPT HASH TABLE EMP BUILD INPUT TABLE PROBE TABLE 24

Hash Join 예제2 > 실행계획 SELECT /*+ use_hash(a b) */ a.empno, a.ename, b.dname FROM emp a, dept b WHERE a.deptno = b.deptno ; --------------------------------------------------------------------------------------- Id Operation Name Starts A-Rows A-Time Buffers Used-Mem --------------------------------------------------------------------------------------- * 1 HASH JOIN 1 12 00:00:00.03 00.03 20 878K (0) 2 TABLE ACCESS FULL DEPT 1 5 00:00:00.01 3 3 TABLE ACCESS FULL EMP 1 14 00:00:00.02 17 --------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - access("a"."deptno"=to_number("b"."deptno")) "DEPTNO" TO NUMBER("B" "DEPTNO")) 25

Cartesian Join > 발생조건 > 특징 > 적용 > Hint 조인되는두집합에조인조건이전혀없는경우 M:M 조인을의미 Cartesian Join 발생원인 - SQL 작성자의실수 - 사용자가특별한목적하에고의적발생 ( 데이터복제 ) Cross Join 이라고도함. 실행계획의특징 - Sort Merge 조인만이 Cartesian 실행계획명기 - 타조인의경우정상적인조인의실행계획으로명기, 단결과로확인가능 사용자가특별한목적하에조인조건없이사용 Cartesian Join 이발생하면 SQL 의조인조건을검증해야함. N/A 26

Cartesian Join -예제 > 실행계획 select a.empno, a.ename, b.dname from emp a, dept b order by b.dname ; 조인조건이빠져있음 ------------------------------------------------------------------------------------------------------------------- Id Operation Name Starts E-Rows A-Rows A-Time Buffers OMem 1Mem Used-Mem ------------------------------------------------------------------------------------------------------------------- 1 SORT ORDER BY 1 56 56 00:00:00.01 14 4096 4096 4096 (0) 2 MERGE JOIN CARTESIAN 1 56 56 00:00:00.01 14 3 TABLE ACCESS FULL DEPT 1 4 4 00:00:00.01 00.01 7 4 BUFFER SORT 4 14 56 00:00:00.01 7 9216 9216 8192 (0) 5 TABLE ACCESS FULL EMP 1 14 14 00:00:00.01 7 ------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------- Id Operation Name Starts E-Rows A-Rows A-Time Buffers OMem 1Mem Used-Mem ----------------------------------------------------------------------------------------------------------------- 1 SORT ORDER BY 1 56 56 00:00:00.01 35 4096 4096 4096 (0) 2 NESTED LOOPS 1 56 56 00:00:00.01 35 3 TABLE ACCESS FULL DEPT 1 4 4 00:00:00.01 7 4 TABLE ACCESS FULL EMP 4 14 56 00:00:00.01 28 ----------------------------------------------------------------------------------------------------------------- 실행계획상에서 Merge Join 일때만 Cartesian 이라는실행계획이보임 27

Sub Query > 발생조건 > 특징 > 적용 SELECT 한결과를조건비교 (>, =, <, IN, ANY, ALL, Exists) 에사용하거나 UPDATE, INSERT, DELETE에사용할때사용되는 Query를이르는말 서브쿼리종류에는 row 기준으로비교할경우 Single Row, Multi Row 가있음 서브쿼리종류에는 column 기준으로비교할경우 Single column, Multi column 가있음 Non Corelate 서브쿼리 : ( 서브쿼리내에서브쿼리와메인쿼리의조인절이없음 ) Corelate 서브쿼리 : ( 서브쿼리내에서브쿼리와메인쿼리의조인절이있음 ) 서브쿼리가조건의비교문으로사용될때연산자가 = 인경우서브쿼리에서나오는결과행의수가 1보다클수없고, Single Row 서브쿼리라함 연산자가 IN, ANY, ALL, EXISTS 등이사용되면 Multi Row 서브쿼리가능 Single Row 서브쿼리는특정한하나의값을메인쿼리에제공하고자할때적용 in 대신에 = 기호를사용해도됨 Multi Column 서브쿼리는보통 Primary Key 컬럼이두개이상인경우에 KEY 값을한꺼번에묶어서비교하기위해자주사용 제공자로사용할건지확인자로사용할건지확인하는습관을들여야함. 28

Sub Query(In) - 예제 > 실행계획 select deptno, empno, ename, job from emp where deptno in (select deptno from dept where loc in ('CHICAGO','DALLAS' )) ; ------------------------------------------------------------------------------------------------------ Id Operation Name Starts E-Rows A-Rows A-Time Buffers ------------------------------------------------------------------------------------------------------ 1 TABLE ACCESS BY INDEX ROWID EMP 1 2 11 00:00:00.01 12 2 NESTED LOOPS 1 3 14 00:00:00.01 8 3 INLIST ITERATOR 1 2 00:00:00.01 5 4 TABLE ACCESS BY INDEX ROWID DEPT 2 2 2 00:00:00.01 5 * 5 INDEX RANGE SCAN DEPT_IDX1 2 2 2 00:00:00.01 3 * 6 INDEX RANGE SCAN IX_EMP_N4 2 2 11 00:00:00.01 3 ------------------------------------------------------------------------------------------------------ Predicate Information (identified by operation id): --------------------------------------------------- 5 - access(("loc"='chicago' CHICAGO OR "LOC"='DALLAS')) 6 - access("deptno"="deptno") 29

Sub Query(=) - 예제 > 실행계획 sselect deptno, empno, ename, job from emp where deptno = (select deptno from dept where loc in ('CHICAGO' )) ; -------------------------------------------------------------------------------------------------------------- Id Operation Name Starts E-Rows A-Rows A-Time Buffers Reads -------------------------------------------------------------------------------------------------------------- 1 TABLE ACCESS BY INDEX ROWID EMP 1 2 6 00:00:00.04 6 4 * 2 INDEX RANGE SCAN IX_EMP_N4 1 5 6 00:00:00.03 4 3 3 TABLE ACCESS BY INDEX ROWID DEPT 1 1 1 00:00:00.02 2 2 * 4 INDEX RANGE SCAN DEPT_IDX1 1 1 1 00:00:00.01 1 1 -------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("deptno"=) 4 - access("loc"='chicago') 30

Sub Query(Any) - 예제 > 실행계획 서브쿼리의결과값중하나의값만만족하여도결과값을리턴 select empno, ename, job, sal from emp where sal > any (select sal from emp where job = 'MANAGER ) ; ------------------------------------------------------------------------------------------------------- Id Operation Name Starts A-Rows A-Time Buffers Used-Mem ------------------------------------------------------------------------------------------------------- 1 MERGE JOIN SEMI 1 5 00:00:00.01 4 2 SORT JOIN 1 6 00:00:00.01 2 2048 (0) 3 TABLE ACCESS BY INDEX ROWID EMP 1 14 00:00:00.01 2 4 INDEX FULL SCAN IX_EMP_N5 1 14 00:00:00.01 1 * 5 SORT UNIQUE 6 5 00:00:00.01 2 2048 (0) 6 TABLE ACCESS BY INDEX ROWID EMP 1 3 00:00:00.01 01 2 * 7 INDEX RANGE SCAN IX_EMP_N1 1 3 00:00:00.01 1 ------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 5 - access(internal_function("sal")>internal_function("sal")) filter(internal_function("sal")>internal_function("sal")) ( ( )) 7 - access("job"='manager') 31

Sub Query(All) - 예제 > 실행계획 서브쿼리의결과값을모두만족되어야결과값을리턴 select empno, ename, job, sal from emp where sal > all (select sal from emp where job = 'MANAGER ) ; ------------------------------------------------------------------------------------------- Id Operation Name Starts A-Rows A-Time Buffers ------------------------------------------------------------------------------------------- * 1 FILTER 1 3 00:00:00.01 41 2 TABLE ACCESS FULL EMP 1 14 00:00:00.01 01 17 * 3 TABLE ACCESS BY INDEX ROWID EMP 12 10 00:00:00.01 24 * 4 INDEX RANGE SCAN IX_EMP_N1 12 16 00:00:00.01 12 ------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter( IS NULL) 3 - filter(lnnvl("sal"<:b1)) 4 - access("job"='manager') 32

Sub Query(Exists) - 예제 > 실행계획 서브쿼리의데이터가존재하는가의여부를따져존재하는값들만결과로리턴 select b.deptno, b.dname from dept b where exists (select 1 from emp a where a.deptno = b.deptno) order by b.deptno ; --------------------------------------------------------------------------------------------- Id Operation Name Starts A-Rows A-Time Buffers Used-Mem --------------------------------------------------------------------------------------------- 1 SORT ORDER BY 1 3 00:00:00.01 5 2048 (0) 2 NESTED LOOPS SEMI 1 3 00:00:00.01 5 3 TABLE ACCESS FULL DEPT 1 5 00:00:00.01 3 * 4 INDEX RANGE SCAN IX_EMP_N2 5 3 00:00:00.01 2 --------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 4 - access("a"."deptno"=to =TO_NUMBER( NUMBER("B" B."DEPTNO")) 33

Sub Query(Sub Query Factoring) - 예제 > 실행계획 with 절을사용하여생성한복잡한쿼리문을임시테이블이실제로저장해두었다가거의테이블과동일하게사용할수있는기능 with x as (select /*+ materialize */ * from emp), y as (select /*+ materialize */ * from dept) select x.empno, x.ename, y.dname from x, y where x.deptno = y.deptno ; ---------------------------------------------------------------------------------------------------------------------- Id Operation Name Starts A-Rows A-Time Buffers Used-Mem ---------------------------------------------------------------------------------------------------------------------- 1 TEMP TABLE TRANSFORMATION 1 12 00:00:00.07 47 2 LOAD AS SELECT 1 1 00:00:00.05 21 262K (0) 3 TABLE ACCESS FULL EMP 1 14 00:00:00.02 16 4 LOAD AS SELECT 1 1 00:00:00.01 7 262K (0) 5 TABLE ACCESS FULL DEPT 1 5 00:00:00.01 01 3 * 6 HASH JOIN 1 12 00:00:00.01 13 688K (0) 7 VIEW 1 5 00:00:00.01 6 8 TABLE ACCESS FULL SYS_TEMP_0FD9FC965_61A13855 1 5 00:00:00.01 6 9 VIEW 1 14 00:00:00.01 7 10 TABLE ACCESS FULL SYS_TEMP_0FD9FC964_61A13855 1 14 00:00:00.01 7 ---------------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 6 - access("x"."deptno"=to_number("y"."deptno")) 34

Semi/Anti Join > 발생조건 > 특징 > 적용 > Hint Sub Query IN, EXISTS 사용시 SEMI 조인발생 NOT IN, NOT EXISTS 사용시 ANTI 조인발생. Sub Query 를 Join 으로바꾸는방식임 일반적인 Join 과매우유사하나메인쿼리는서브쿼리의속성사용불가 Nested Loop, Sort Merge, Hash Join 모두사용가능 Semi Join 은 Exists Subquery 사용시 Filter 와같이첫번째만족하는조건을만나면즉시리턴함. Anti Join 은일반 join 과달리값이동일하지않은 row 를탐색함. Sub Query 사용시 Optimizer 가 Semi Join 및 Anti Join 을적용함. Sub Query 상에 use_nl, use_merge, use_hash 사용 35

Semi Join(Nested Loop Join) -예제 > 실행계획 select b.deptno, b.dname from dept b where exists ( select 1 from emp a where a.deptno = b.deptno ) order by b.deptno ; --------------------------------------------------------------------------------------------- Id Operation Name Starts A-Rows A-Time Buffers Used-Mem --------------------------------------------------------------------------------------------- 1 SORT ORDER BY 1 3 00:00:00.02 5 2048 (0) 2 NESTED LOOPS SEMI 1 3 00:00:00.02 02 5 3 TABLE ACCESS FULL DEPT 1 5 00:00:00.01 3 * 4 INDEX RANGE SCAN IX_EMP_N2 5 3 00:00:00.01 2 --------------------------------------------------------------------------------------------- 36

Semi Join(Sort Merge Join) -예제 > 실행계획 select a.empno, a.ename, a.deptno from emp a where exists ( select 1 from dept b where a.deptno = b.deptno ) order by a.deptno ; ------------------------------------------------------------------------------------------------------ Id Operation Name Starts A-Rows A-Time Buffers Used-Mem ------------------------------------------------------------------------------------------------------ 1 MERGE JOIN SEMI 1 12 00:00:00.07 7 2 TABLE ACCESS BY INDEX ROWID EMP 1 13 00:00:00.04 04 4 3 INDEX FULL SCAN IX_EMP_N2 1 13 00:00:00.01 2 * 4 SORT UNIQUE 13 12 00:00:00.03 3 2048 (0) 5 TABLE ACCESS FULL DEPT 1 5 00:00:00.03 3 ------------------------------------------------------------------------------------------------------ 37

Semi Join(Hash Join) -예제 > 실행계획 select b.deptno, b.dname from dept b where exists ( select /*+ use_hash(a) */ 1 from emp a where a.deptno = b.deptno ) order by b.deptno ; --------------------------------------------------------------------------------------------- Id Operation Name Starts A-Rows A-Time Buffers Used-Mem --------------------------------------------------------------------------------------------- 1 SORT ORDER BY 1 3 00:00:00.02 4 2048 (0) * 2 HASH JOIN SEMI 1 3 00:00:00.02 02 4 701K (0) 3 TABLE ACCESS FULL DEPT 1 5 00:00:00.02 3 4 INDEX FULL SCAN IX_EMP_N2 1 13 00:00:00.01 1 --------------------------------------------------------------------------------------------- 38

Hash Join Right (Semi/Anti) Join > 발생조건 > 특징 > 적용 Semi 조인에서서브쿼리가소량일경우 Hash 조인과함께서브쿼리가먼저 Driving 되는조인방식 Semi 조인은항상메인쿼리가수행된후서브쿼리의데이터가존재하는지를체크하는방식 따라서서브쿼리는항상후행집합이될수밖에없음. 하지만 10g 부터 Plan 상에 Hash Join Right (Semi/Anti/Outer) 이나오게되면서브쿼리가 Driving 집합이됨. 서브쿼리집합이메인쿼리의집합보다적을때 10g 버전부터사용가능 39

Hash Join Right Semi - Concept >Full Hash Right Semi Full select a.empno, a.sal from big_emp a where exists (select /*+ use_hash(b) h(b) */ DEPT b.deptno from dept b where b.deptno = a.deptno ) ; HASH TABLE BIG_EMP 서브쿼리집합은 BUILD INPUT 이될수없으나 10g 부터 HASH JOIN RIGHT(SEMI/ANTI) JOIN 을이용하면가능함 BUILD INPUT TABLE PROBE TABLE 40

Hash Join Right Semi -예제 > 실행계획 select a.empno, a.sal from big_emp a where exists (select b.deptno from dept b where b.deptno = a.deptno ) ; ------------------------------------------------------------------------------------------- Id Operation Name Starts A-Rows A-Time Buffers Used-Mem ------------------------------------------------------------------------------------------- * 1 HASH JOIN RIGHT SEMI 1 24576 00:00:00.05 1878 980K (0) 2 TABLE ACCESS FULL DEPT 1 5 00:00:00.01 3 3 TABLE ACCESS FULL BIG_EMP 1 28672 00:00:00.03 1875 ------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - access("a"."deptno"=to_number("b"."deptno")) 41

Anti Join(Nested Loop Join) -예제 > 실행계획 select b.deptno, b.dname from dept b where not exists ( select 1 from emp a where a.deptno = b.deptno ) order by b.deptno ; ---------------------------------------------------------------------------------------------- Id Operation Name Starts A-Rows A-Time Buffers Used-Mem ---------------------------------------------------------------------------------------------- 1 SORT ORDER BY 1 2 00:00:00.11 5 2048 (0) 2 NESTED LOOPS ANTI 1 2 00:00:00.11 5 3 TABLE ACCESS FULL DEPT 1 5 00:00:00.10 3 * 4 INDEX RANGE SCAN IX_EMP_N2 5 3 00:00:00.01 2 ---------------------------------------------------------------------------------------------- 42

Anti Join(Sort Merge Join) -예제 > 실행계획 select a.empno, a.ename, a.deptno from emp a where not exists ( select /*+ use_merge(b) */ 1 from dept b where a.deptno = b.deptno ) order by a.deptno ; ---------------------------------------------------------------------------------------- Id Operation Name Starts A-Rows A-Time Buffers Used-Mem ---------------------------------------------------------------------------------------- 1 MERGE JOIN ANTI 1 2 00:00:00.04 19 2 SORT JOIN 1 14 00:00:00.03 16 2048 (0) 3 TABLE ACCESS FULL EMP 1 14 00:00:00.02 16 * 4 SORT UNIQUE 14 12 00:00:00.01 01 3 2048 (0) 5 TABLE ACCESS FULL DEPT 1 5 00:00:00.01 3 ---------------------------------------------------------------------------------------- 43

Anti Join(Hash Join) -예제 > 실행계획 select b.deptno, b.dname from dept b where not exists ( select /*+ use_hash(a) h( */ 1 from emp a where a.deptno = b.deptno ) order by b.deptno ; --------------------------------------------------------------------------------------------- Id Operation Name Starts A-Rows A-Time Buffers Used-Mem --------------------------------------------------------------------------------------------- 1 SORT ORDER BY 1 3 00:00:00.02 4 2048 (0) * 2 HASH JOIN ANTI 1 3 00:00:00.02 4 701K (0) 3 TABLE ACCESS FULL DEPT 1 5 00:00:00.02 3 4 INDEX FULL SCAN IX_EMP_N2 1 13 00:00:00.01 1 --------------------------------------------------------------------------------------------- 44

Hash Join Right Anti - Concept >Full Hash Right Anti Full select a.empno, a.sal from big_emp a where not exists (select /*+ use_hash(b) h(b) */ DEPT b.deptno from dept b where b.deptno = a.deptno ) ; HASH TABLE BIG_EMP 서브쿼리집합은 BUILD INPUT이될수없으나 10g부터 HASH JOIN RIGHT(SEMI/ANTI) JOIN을이용하면가능함 전체건을 Scan 한다음 DEPT 테이블에없는건만조인됨 BUILD INPUT TABLE PROBE TABLE 45

Hash Join Right Anti -예제 > 실행계획 select a.empno, a.sal ; from big_emp a where not exists (select b.deptno from dept b where b.deptno = a.deptno ) ------------------------------------------------------------------------------------------- Id Operation Name Starts A-Rows A-Time Buffers Used-Mem ------------------------------------------------------------------------------------------- * 1 HASH JOIN RIGHT ANTI 1 4096 00:00:00.03 03 522 980K (0) 2 TABLE ACCESS FULL DEPT 1 5 00:00:00.01 3 3 TABLE ACCESS FULL BIG_EMP 1 28672 00:00:00.01 519 ------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - access("a"."deptno"=to_number("b"."deptno")) 46

Index Join > 발생조건 > 특징 > 적용 테이블액세스없이하나이상의인덱스들을결합하여쿼리를수행 사용된모든컬럼이어떤인덱스에라도존재 비교연산자가 Equal( = ) 이아니어도인덱스조인에참여가능 반드시인덱스의선두칼럼이아니어도인덱스조인에참여가능 조건절을기준으로인덱스조인을결정 실행계획상에서는 Hash Join 으로수행되는것으로보임 검색에유리한인덱스가없을때인덱스머지를통해검색범위를줄이고자할때 > Hint /*+ index_join( 테이블명또는테이블별칭 ) */ 47

Index Join - 예제 > 실행계획 인덱스 Lay out 1 : JOB 인덱스 Lay out 2 : mgr + empno select /*+ index_join(emp) */ empno, job, mgr from emp where job = 'CLERK' and mgr = 7788 ; --------------------------------------------------------------------------------------------------- Id Operation Name Starts A-Rows A-Time Buffers Used-Mem --------------------------------------------------------------------------------------------------- * 1 VIEW index$_join$_001 1 1 00:00:00.01 3 * 2 HASH JOIN 1 1 00:00:00.01 3 883K (0) * 3 INDEX RANGE SCAN IX_EMP_N1 1 4 00:00:00.01 1 * 4 INDEX RANGE SCAN IX_EMP_N3 1 1 00:00:00.01 01 2 --------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter(("mgr"='7788' AND "JOB"='CLERK')) 2 - access(rowid=rowid) 3 - access("job"='clerk') 4 - access("mgr"='7788') 48

Outer Join > 특징 > 적용 Nested Loop, Sort Merge, Hash, Full Outer Join 형태 Nested Loop, Sort Merge, Hash Join 은앞장정리부분참조 Full Outer Join은첫번째집합을기준으로 Outer Join을하고, 두번째집합을기준으로 Anti 조인을한다음 union all Operation 을적용한다. 아우터조인되어있는집합에대응되는로우가없더라도기준집합의모든로우들을리턴하는조인 조인및 where 조건컬럼뒤에 (+) 기호로발생 49

Outer Join(Nested Loop) - 예제 > 실행계획 select a.empno, a.ename, b.dname from emp a, dept b where a.deptno = b.deptno(+) ; ------------------------------------------------------------------------------------- Id Operation Name Starts E-Rows A-Rows A-Time Buffers ------------------------------------------------------------------------------------- 1 NESTED LOOPS OUTER 1 1 14 00:00:00.01 60 2 TABLE ACCESS FULL EMP 1 1 14 00:00:00.01 17 * 3 TABLE ACCESS FULL DEPT 14 1 12 00:00:00.01 43 ------------------------------------------------------------------------------------- Predicate Information (identified d by operation id): --------------------------------------------------- 3 - filter("a"."deptno"=to_number("b"."deptno")) ( 50

Outer Join(Sort Merge) - 예제 > 실행계획 select /*+ use_merge(a b) */ a.empno, a.ename, b.dname from emp a, dept b where a.deptno = b.deptno(+) ; ---------------------------------------------------------------------------------------- Id Operation Name Starts A-Rows A-Time Buffers Used-Mem ---------------------------------------------------------------------------------------- 1 MERGE JOIN OUTER 1 14 00:00:00.01 19 2 SORT JOIN 1 14 00:00:00.01 16 2048 (0) 3 TABLE ACCESS FULL EMP 1 14 00:00:00.01 16 * 4 SORT JOIN 14 12 00:00:00.01 3 2048 (0) 5 TABLE ACCESS FULL DEPT 1 5 00:00:00.01 3 ---------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 4 - access("a"."deptno"=to_number("b"."deptno")) filter("a"."deptno"=to_number("b"."deptno")) 51

Outer Join(Hash) - 예제 > 실행계획 select /*+ use_hash(a h( b) */ a.empno, a.ename, b.dname from emp a, dept b where a.deptno = b.deptno(+) ; --------------------------------------------------------------------------------------- Id Operation Name Starts A-Rows A-Time Buffers Used-Mem --------------------------------------------------------------------------------------- * 1 HASH JOIN OUTER 1 14 00:00:00.01 20 809K (0) 2 TABLE ACCESS FULL EMP 1 14 00:00:00.01 16 3 TABLE ACCESS FULL DEPT 1 5 00:00:00.01 4 --------------------------------------------------------------------------------------- Predicate Information (identified d by operation id): --------------------------------------------------- 1 - access("a"."deptno"=to_number("b"."deptno")) ( 52

Outer Join(Full Outer) - 예제 > 실행계획 select a.empno, a.ename, b.dname from emp a full outer join dept b on (a.deptno= b.deptno) ; ----------------------------------------------------------------------------------- Id Operation Name Starts A-Rows A-Time Buffers ----------------------------------------------------------------------------------- 1 VIEW 1 16 00:00:00.01 65 2 UNION-ALL 1 16 00:00:00.01 65 3 NESTED LOOPS OUTER 1 14 00:00:00.01 60 4 TABLE ACCESS FULL EMP 1 14 00:00:00.01 17 * 5 TABLE ACCESS FULL DEPT 14 12 00:00:00.01 43 6 NESTED LOOPS ANTI 1 2 00:00:00.01 5 7 TABLE ACCESS FULL DEPT 1 5 00:00:00.01 3 * 8 INDEX RANGE SCAN IX_EMP_N2 5 3 00:00:00.01 2 ----------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 5 - filter("a"."deptno"=to_number("b"."deptno")) 8 - access("a"."deptno"=to =TO_NUMBER( NUMBER("B" B."DEPTNO")) 53

Outer Join(Full Outer) - 예제 > Query Transformation select a.empno, a.ename, b.dname from emp a full outer join dept b on (a.deptno= b.deptno) ; select empno, ename, dname from ( select a.empno, a.ename, b.dname from emp a, dept b where a.deptno = b.deptno(+) union all select null, null, a.dname from dept a where not exists (select 1 ) ; from emp b where b.deptno = a.deptno ) 54 Query Transformation 실행계획이동일함 ------------------------------------------ Id Operation Name ------------------------------------------ 1 VIEW 2 UNION-ALL 3 NESTED LOOPS OUTER 4 TABLE ACCESS FULL EMP * 5 TABLE ACCESS FULL DEPT 6 NESTED LOOPS ANTI 7 TABLE ACCESS FULL DEPT * 8 INDEX RANGE SCAN IX_EMP_N2 ------------------------------------------

Hash Join Right Outer > 발생조건 > 특징 > 적용 Outer Join 이 Hash Join으로풀리는경우 (+) 기호가붙은칼럼의테이블이아주작은테이블일경우 Driving 으로수행됨 Outer Join 시 9i 버전까지는무조건 (+) 기호가붙지않은칼럼의테이블이 Driving 되었음 10g 부터 (+) 기호가붙어있더라도소량의테이블이라면 Driving 될수있게됨 Hash Join Right (Semi/Anti) 와같은방식임 10g 버전부터사용가능 > Hint /*+ use_hash( 테이블명혹은 alias) */ 55

Hash Join Right Outer -예제 >Full Hash Right Outer Full select /*+ use_hash(a b) */ a.dname, b.empno, ename from dept a, big_emp b where a.deptno(+) = b.deptno ; DEPT HASH TABLE BIG_EMP (+) 기호가붙은쪽테이블은 BUILD INPUT 이될수없으나 10g 부터 HASH JOIN RIGHT OUTER JOIN 을이용하면가능함 BUILD INPUT TABLE PROBE TABLE 56

Hash Join Right Outer -예제 > 실행계획 select /*+ use_hash(a b) */ a.dname, b.empno, ename from dept a, big_emp b where a.deptno(+) = b.deptno ; -------------------------------------------------------------------------------------------- Id Operation Name Starts A-Rows A-Time Buffers Used-Mem -------------------------------------------------------------------------------------------- * 1 HASH JOIN RIGHT OUTER 1 5770 00:00:00.13 491 1523K (0) 2 TABLE ACCESS FULL DEPT 1 5 00:00:00.02 24 3 TABLE ACCESS FULL BIG_EMP 1 5770 00:00:00.03 467 -------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - access("a"."deptno"="b"."deptno") 57

Partition Outer Join > 개념 년별또는월별집계데이터를나타낼때특정년혹은특정월에데이터가없더라도생성하여나타냄. 주로 OLAP 에서많이활용함 요구사항 테이블구조 Select yymm From Year_month Where yymm = 2002 Select deptno, yymm, sale_amt from dept_sale_history 58

Partition Outer Join -예제 > 기존방식 SELECT e.deptno, m.yymm, NVL(e.sale_amt,0) amt,0) FROM year_month m LEFT OUTER JOIN dept_sale_history e ON (m.yymm = e.yymm AND e.deptno = 10) WHERE m.yymm like '2002% Union all SELECT e.deptno, m.yymm, NVL(e.sale_amt,0) FROM year_month m LEFT OUTER JOIN dept_sale_history e ON (m.yymm = e.yymm AND e.deptno = 20) WHERE m.yymm like '2002% ; > 해결방법 SELECT e.deptno, m.yymm, NVL(e.sale_amt,0) FROM year_month m LEFT OUTER JOIN dept_sale_history e PARTITION BY (e.deptno) ON (m.yymm = e.yymm ) WHERE m.yymm like '2002% ; 59

Partition Outer Join -예제 > 기존방식 SELECT e.deptno, m.yymm, NVL(e.sale_amt,0) amt,0) FROM year_month m LEFT OUTER JOIN dept_sale_history e ON (m.yymm = e.yymm AND e.deptno = 10) WHERE m.yymm like '2002% Union all SELECT e.deptno, m.yymm, NVL(e.sale_amt,0) FROM year_month m LEFT OUTER JOIN dept_sale_history e ON (m.yymm = e.yymm AND e.deptno = 20) WHERE m.yymm like '2002% ; ----------------------------------------------------------------------------------------------------- Id Operation Name Starts A-Rows A-Time Buffers Used-Mem ----------------------------------------------------------------------------------------------------- 1 UNION-ALL 1 24 00:00:00.01 01 29 * 2 HASH JOIN OUTER 1 12 00:00:00.01 15 1342K (0) * 3 TABLE ACCESS FULL YEAR_MONTH 1 12 00:00:00.01 7 * 4 TABLE ACCESS FULL DEPT_SALE_HISTORY 1 5 00:00:00.01 8 * 5 HASH JOIN OUTER 1 12 00:00:00.01 14 1343K (0) * 6 TABLE ACCESS FULL YEAR_MONTH 1 12 00:00:00.01 7 * 7 TABLE ACCESS FULL DEPT_SALE_HISTORY 1 4 00:00:00.01 7 ----------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("m"."yymm"="e"."yymm") 3 - filter("m"."yymm" LIKE '2002%') 4 - filter(("e"."deptno"=10 AND "E"."YYMM" LIKE '2002%')) 5 - access("m"."yymm"="e"."yymm") 6 - filter("m"."yymm" (""" " LIKE '2002%')') 7 - filter(("e"."deptno"=20 AND "E"."YYMM" LIKE '2002%')) 60

Partition Outer Join -예제 > 해결방법 SELECT e.deptno, m.yymm, mm NVL(e.sale_amt,0) amt FROM year_month m LEFT OUTER JOIN dept_sale_history e PARTITION BY (e.deptno) ON (m.yymm = e.yymm ) WHERE m.yymm like '2002% ; ------------------------------------------------------------------------------------------------------------- Id Operation Name Starts A-Rows A-Time Buffers Used-Mem ------------------------------------------------------------------------------------------------------------- 1 VIEW 1 24 00:00:00.01 14 2 MERGE JOIN PARTITION OUTER 1 24 00:00:00.01 14 3 SORT JOIN 3 25 00:00:00.01 01 7 2048 (0) * 4 TABLE ACCESS FULL YEAR_MONTH 1 12 00:00:00.01 7 * 5 SORT PARTITION JOIN 25 9 00:00:00.01 7 2048 (0) 6 TABLE ACCESS FULL DEPT_SALE_HISTORY 1 9 00:00:00.01 7 ------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 4 - filter("m"."yymm" LIKE '2002%') 5 - access("m"."yymm"="e"."yymm") filter("m"."yymm"="e"."yymm") 61

Star Query Transformation > 개념 > 제약사항 > Hint 소량의데이터를가진여러개의디맨젼테이블과팩트테이블의개별비트맵인덱스를이용하여처리범위를줄이는조인방식 B-TREE 인덱스와는다르게독립적인 BIT MAP INDEX 로 LIKE, BETWEEN 등범위검색에서도 BIT MAP 인덱스머지가일어남. 내부적으로옵티마이져가질의를변형하여실행계획을생성함. FROM 절에여러 FACT 테이블이조인된것을 WHERE 절에서브쿼리조인으로바꿈. 하나의팩트테이블에최소한 2 개이상의디맨션테이블이있어야한다. 팩트테이블의외부키에는반드시비트맵인덱스가존재해야한다. 팩트테이블에반드시통계정보가생성되어있어야한다. 파라메터 (STAR_TRANSFORMATION_ENABLED) 가 TRUE 이어야함. 바인드변수를사용하면안된다.( 반드시상수인경우에발생됨 ) /*+ STAR_TRANSFORMATION */ 62

Star Query Transformation -예제 > STAR_TRANSFORMATION 예제 create bitmap index idx_sales_n01 _ on sales(sale_date); create bitmap index idx_sales_n02 on sales(cust_id); alter session set star_transformation_enabled _ = true; Select /*+ STAR_TRANSFORMATION */ A.QUTER, B,STATE,, SUM(C.AMOUNT) FROM CARENDAR A, CUSTOMER B, SALES C WHERE A.SALE_DATE = C.SALE_DATE AND B.CUST_ ID = C.CUST_ ID AND B.STATE = CA AND A.QUTER = 200404 Query Transformation SELECT A.QUTER, B,STATE, SUM(C.AMOUNT) FROM CARENDAR A, CUSTOMER B, SALES C WHERE SALES_DATE IN (SELECT SALES_DATE FROM CARENDAR WHERE QUTER = 200404 ) AND CUST_ID IN (SELECT CUST_ID FROM CUSTOMER WHERE STATE = CA ) 63

Oracle Data Join Method- 정리 Nested Loop Join Sort Merge Join Hash Join Cartesian Join ( 혹은 Cross Join) Sub Query (=,In, Any, All, Exists, Subquery Factoring) Semi Join (Nested Loop, Sort Merge, Hash, Hash Join Right) Anti Join (Nested Loop, Sort Merge, Hash, Hash Join Right) Index Join Outer Join (Full,Nested Loop, Sort Merge, Hash, Hash Join Right) Partition Outer Join Star Query Transformation 64

Special Key Note Oracle Data Join Method 감사합니다. 65