SELECT /*+ ORDERED USE_NL(B) */ --B와 조인할때 NL조인사용
*
FROM ITEM A
, UITEM B
WHERE A.ITEM_ID = B.ITEM_ID --1
AND A.ITEM_TYPE_CD = '100100' --2
AND A.SALE_YN = 'Y' --3
AND B.SALE_YN = 'Y' --4
각각의 데이터 추출 하여 조인
begin_point = 0;
for(i=0;i<I_MAX;i++)
{
for(j=begin_point;j<J_MAX;j++)
{
while(d.dept_no=e.deptno)
{
begin_point = j +1
}
break; //조인서칭후 루프탈출
}
}
-위 예문만을 위한 최적의 인덱스SELECT /*+ ORDERED USE_MERGE(B) */ -- B와조인할때 소트머지사용
*
FROM ITEM A
, UITEM B
WHERE A.ITEM_ID = B.ITEM_ID --1
AND A.ITEM_TYPE_CD = '100100' --2
AND A.SALE_YN = 'Y' --3
AND B.SALE_YN = 'Y' --4
해시맵을 만들때, 해시 버킷을 생성하고 해시함수를 통해 반환된 값으로 해시 버킷을 찾아가 해시 체인을 구성
해시버킷 : 해시 배열의 대표값을 포함한 해시 저장소라고생각하면될듯..
해시함수가 f(x) = mod(x, 10) 이라고할때, 어떤값(정수)이 입력되든 변환될수 있는 값은 0~9까지 이므로 해시 버킷은 총 10개가 만들어짐.
0~99까지 숫자가 입력된다 가정하면 아래와 같은 해시맵을 만듬, 좌측 숫자집합은 위에서 아래로, 좌에서 우순서로 입력된다고 가정
그림에서 좌측굵은 0~9숫자는 해시버킷(대표값?) 오른쪽숫자집합이 입력될때, 해시함수의 반환값을 받아 해당되는 해시버킷의 해시체인으로 연결(버킷옆의 화살표로이어진 체인들)
오라클에서 해시 조인을 위해 해시 맵을 만들때 두 테이블중 작은 테이블을 읽어 만듬.
큰테이블을 읽어 해시함수를 통해 해시 버킷을 찾아가 실제 데이터를 찾음
작은테이블(Build Input), 큰테이블 (Probe Input)
해시 맵은 해시 함수를 사용해 해시 함수가 반환하는값으로 해시 버킷을 찾아 해시 체인에 연결하면서 만드. 해시맵에서 찾을때도 마찬가지, 해시함수가 반환하는 값으로 버킷을 찾고, 버킷에 할당된 체인을 검색하면서 해당 데이터를 찾아감.
아래 그림에서 B테이블(Build Input)을 읽어 해시 함수를 통해 해시 맵을 만들고, A테이블(Probe Input)을 읽어 나가면서 85값을 해시함수에 대입해 찾아가야할 버킷을 확인(버킷 5번), 버킷에 연결된 해시체인을 검색해 얻은 85를 찾아 조인.
해시맵에는 조인컬럼과 select절에 사용한 컬럼까지 포함, SQL작성시 꼭 필요한 컬럼만 기술하는것이 PGA사용량을 줄일 수 있음.
해시조인 유도법 : USE_HASH힌트사용.
SELECT /*+ ORDERED USE_HASH(E) */ --E와조인할때 해시조인사용
*
FROM DEPT D
, EMP E
WHERE 1 = 1
AND D.DEPNO = E.DEPTNO
사용자가 BUILD INPUT을 선택하려면 추가힌트를 사용해야함. 두개테이블만으로 해시 조인할경우 ORDERED(나열순)나 LEADING(지정순) 힌트를 사용해 BUILD INPUT을 지정가능, 3개이상 테이블을 가지고 해시조인을 할때, BUILD INPUT을 사용자가 지정하려면 SWAP_JOIN_INPUTS(테이블명) 힌트를 사용해야함.
BUILD INPUT을 옵티마이저에게 선택하도록 맡기려면 USE_HASH만사용한다. 오라클이 통계정보를 확인해 더작은 테이블을 BUILD INPUT으로 선택함
BUILD INPUT이 지나치게 큰 테이블로 선택되면 PGA내 해시영역 안에 적재가 힘들어지고 디스크공간을 사용하게됨, 이럴경우 해시조인 성능이 크게 떨어짐. 그래서 BUILD INPUT을 제어하는방법을 꼭 알고있어야함.
SELECT ~
FROM ~
WHERE A.KEY = B.KEY
AND B.KEY = '30'
첫번째 테이블에 조인컬럼 기준으로 인덱스가 있어 정렬부하 발생 안할때
Group by 또는 Order by등으로 이미정렬한 서브쿼리와 조인시도시 두번째 테이블의 양이적을때
테이블의 양이 매우 커서 NL조인이 힘들고, 조건이 등치조건이 아니어서 해시조인도 힘들때
대용량 테이블을 조인시도하는데 조인 컬럼에 적당한 인덱스가 없어서 NL조인이 힘들때
조인컬럼에 인덱스가 있지만 드라이빙 테이블의 건수가 많아 INNER테이블로 많은 양의 랜덤액세스가 발생할때
두 테이블의 양이 많아 소트머지조인 시도시 정렬로 인한 부하가 클때
SELECT A.*
,B.*
FROM ITEM A
, UITEM B
WHERE A.ITEM_ID = B.ITEM_ID
AND A.ITEM_TYPE_CD = '100100'
AND A.SALE_YN = 'Y'
AND B.SALE_YN = 'Y'
REGEXP_SUBSTR(SUB, '[^$]+', 1, 1) : DNAME
REGEXP_SUBSTR(SUB, '[^$]+', 1, 2) : LOC
(SELECT DNAME || '$' || LOC FROM
) SUB
또다른 방법 > 컬럼길이보다 길게 PAD값을주고 가져와서 잘라쓰기
TRIM(SUBSTR(SUB,1,20)) :DNAME
TRIM(SUBSTR(SUB,21,20)) : LOC
(SELECT LPAD(DNAME, 20 || LPAD(LOC,20) ~~) SUB