12
오오오 오오 HASH JOIN USE_HASH, ORDERED 오오오 , 오오오오오 (topcredu.co.kr)

(추천오라클힌트교육)해시조인, Hash join, use_hash, ordered

  • Upload
    3-2

  • View
    837

  • Download
    0

Embed Size (px)

Citation preview

Page 1: (추천오라클힌트교육)해시조인, Hash join, use_hash, ordered

오라클 힌트HASH JOIN

USE_HASH, ORDERED

이종철 , 탑크리에듀 (topcredu.co.kr)

Page 2: (추천오라클힌트교육)해시조인, Hash join, use_hash, ordered

해시조인 (HASH JOIN, USE_HASH)

해시조인은 두테이블 중 작은 테이블 (Build Input, Driving Table) 을 메모리에 조인키를 기반으로 해시테이블을 생성하고 해시테이블내에 행들을 위치시키기 위해 해시함수를 이용하며 나머지 테이블을 스캔하면서 메모리에 있는 해시테이블과 조인 조건을 만족하는 데이터를 찾는 조인이다 .

중첩루프조인과 같이 조인시 발생하는 랜덤액세스에 대한 부하가 없는 조인방식이다 .

관계형 데이터베이스에서 가장 비용이 많이 들어가는 조인방법으로 주로 작은 테이블과 큰 테이블의 조인 시 사용되며 , 드라이빙 조건과 상관없이 좋은 성능을 발휘할 수 있는 조인 방법이며 대체로 제일 빠르다 .

Page 3: (추천오라클힌트교육)해시조인, Hash join, use_hash, ordered

HASH JOIN Example

• [MYEMP1_OLD 테이블이 드라이비빙 , BUILD INPUT]

SELECT /*+ ORDERED USE_HASH(E2) */ EMPNO FROM MYEMP1_OLD E1, MYEMP1 E2WHERE E1.EMPNO = E2.EMPNO

Page 4: (추천오라클힌트교육)해시조인, Hash join, use_hash, ordered

해시조인 (HASH JOIN, USE_HASH)

해시 조인은 안티 조인과 병렬처리와 잘 맞고 범위검색이 아닌 동등 비교 (Equi-Join, where 절에서 등호로 비교하는 경우 ) 에 더 적합하다 . 드라이빙이 되는 Build Input 의 해시키 컬럼에 중복 값이 없어야 좋은 성능을 낸다 .

해시테이블을 만드는 단계는 전체범위처리하며 Probe Input 을 스캔하는 단계는 NL조인처럼 부분 범위 처리 가능 하다 . 생성하는 비용이 수반됨으로 드라이빙 테이블 (Build Input) 이 작을 때 효과적이며 PGA 내부 Private SQL Area 의 Runtime-Area 내부 SQL Work Area 에 할당되는 Hash Area 에 담길 정도로 작아야 한다 .

소트 머지 조인하기에는 두 테이블이 너무 커 소트 부하가 심할 때 유리하며 수행 빈도가 낮고 쿼리 수행 시간이 오래 걸리는 대용량 테이블을 조인 할 때 좋으며 해시테이블은 단 하나의 쿼리를 위해 생성되고 조인이 끝나면 곧바로 소멸하는 자료구조이다 . USE_HASH : HASH JOIN 을 하라는 힌트 NO_USE_HASH : HASH JON 을 하지 말라는 힌트

Page 5: (추천오라클힌트교육)해시조인, Hash join, use_hash, ordered

ORDERED 힌트 ORDERED 힌트는 FROM 뒤에 기술되는 테이블의 순서대로 조인이 일어나도록 해주는 구문이며 대부분 단독으로는 사용되지 않고 USE_NL( 중첩 루프 조인을 유도 ),

USE_MERGE( 머지 소트 조인을 유도 ), USE_HASH(HASH 조인을 유도 ) 등과 같이 사용된다 .

USE_NL/USE_MERGE/USE_HASH 등의 인자로 사용되는 테이블은 FROM 절에서 두 번째로 나타나는 테이블 이어야 하는데 FROM 절에서 처음 나타나는 테이블이 드라이빙 테이블 (OUTER/DRIVING TABLE) 이 되고 나중에 나타나는 테이블이 PROBED TABLE(INNER TABLE) 이 된다 .

Page 6: (추천오라클힌트교육)해시조인, Hash join, use_hash, ordered

HASH_JOIN, ORDERED 드라이빙 테이블 선정-- ordered, use_hash 힌트를 이용한 조인시 드라이빙 테이블의 선정 -- 실습환경 오라클 11g, MYEMP1 은 1000 만건 , MYDEPT1 은 7 건-- MYEMP1, MYDEPT1 테이블의 DEPTNO 칼럼에 인덱스 생성되어 있다 . -- 생성된 인덱스 확인select a.index_name, a.column_name, b.visibility from USER_IND_COLUMNS a, USER_INDEXES b where a.table_name in ('MYEMP1', 'MYDEPT1') and a.index_name = b.index_name and a.column_name = 'DEPTNO' order by a.index_name, a.column_name;

IDX_MYEMP1_DEPTNO DEPTNO VISIBLEPK_MYDEPT1 DEPTNO VISIBLE

Page 7: (추천오라클힌트교육)해시조인, Hash join, use_hash, ordered

HASH_JOIN, ORDERED 드라이빙 테이블 선정-- 힌트 사용안하고 했을 때는 중첩루프조인이 걸린다 . select e.ename, d.dname from mydept1 d, myemp1 e where e.deptno = d.deptnoand e.deptno = '1';

-- 이번에는 NO_USE_NL 을 이용하여 중첩루프 조인을 하지 말라고 하면 머지조인으로 실행을 한다 .select /*+ no_use_nl(e d) */ e.ename, d.dnamefrom mydept1 d, myemp1 ewhere e.deptno = d.deptnoand e.deptno = '0';

Page 8: (추천오라클힌트교육)해시조인, Hash join, use_hash, ordered

HASH_JOIN, ORDERED 드라이빙 테이블 선정-- 해시조인을 이용해 보자 . use_hash 의 인자는 비드라이빙(probe input) 을 준다 . ORDERED 를 사용했으므로 MYDEPT1 이 드라이빙 (Build Input)select /*+ ordered use_hash(e) */ e.ename, d.dnamefrom mydept1 d, myemp1 ewhere e.deptno = d.deptnoand e.deptno = '0';-- 해시조인인데 건수많은 myemp1 이 드라이빙 테이블(Build Input), 좋은 모습이 아니며 느리다 .select /*+ ordered use_hash(d) */ e.ename, d.dnamefrom myemp1 e, mydept1 dwhere e.deptno = d.deptnoand e.deptno = '0';

Page 9: (추천오라클힌트교육)해시조인, Hash join, use_hash, ordered

HASH_JOIN, ORDERED 드라이빙 테이블 선정-- ORDERED 힌트를 사용하지 않고 USE_HASH 에 인자를 2 개 , d, e 순서관계없이 작은 테이블을 Build Input 으로select /*+ use_hash(e d) */ e.ename, d.dnamefrom myemp1 e, mydept1 dwhere e.deptno = d.deptnoand e.deptno = '0';

Page 10: (추천오라클힌트교육)해시조인, Hash join, use_hash, ordered

HASH_JOIN, ORDERED 드라이빙 테이블 선정-- USE_HASH 인자로 하나만 주는 경우는 주의요망 ! -- USE_HASH 인자는 비드라이빙 (Probe Input) 이 오는데 , 아래와 같이 d 를 주었다는 이야기는 e 즉 큰테이블인 MYEMP1 을 드라이빙 (Build Input) 하라는 뜻이므로 한트를 무시해 버린다 .( 중첩루프걸림 ) 강제로 해시조인이 걸리게 하려면 강압적인 힌트 ORDERED와 같이 사용하면 된다 . 해시조인 실행시 기본적으로 오라클은 작은 테이블을 메모리에 해시테이블로 구성되도록 한다 .select /*+ use_hash(d) */ e.ename, d.dnamefrom mydept1 d, myemp1 ewhere e.deptno = d.deptnoand e.deptno = '0';

Page 11: (추천오라클힌트교육)해시조인, Hash join, use_hash, ordered

HASH_JOIN, ORDERED 드라이빙 테이블 선정-- USE_HASH 인자로 하나만 주는 경우는 주의요망 ! -- USE_HASH 인자는 비드라이빙 (Probe Input) 이 오는데 , 아래와 같이 큰테이블 e 를 주었다는 이야기는 d 즉 작은테이블인 MYDEPT1 을 드라이빙 (Build Input) 하라는 뜻이므로 원하는대로 잘 돌아간다 .select /*+ use_hash(e) */ e.ename, d.dnamefrom mydept1 d, myemp1 ewhere e.deptno = d.deptnoand e.deptno = '0';

Page 12: (추천오라클힌트교육)해시조인, Hash join, use_hash, ordered

This practice makes Expert!

PL/SQL단기속성 (1일완성 )SQL힌트 /튜닝 (단기 2일교육 )SQL기초과정