본문 바로가기
공부/DB

[중첩루프조인] 오라클 조인 Nested Loop Join

by 미네밍 2019. 12. 2.

Nested Loop Join

두 개 이상의 테이블 구조에서 하나의 테이블(Driving/Outer Table)을 기준으로, 순차적으로 (Driven/Inner Table)의 Row 를 조인하여 원하는 데이터를 추출하는 방식의 조인.
 
추출되는 Row 가 많아질 수록 성능이 현저히 떨어지고, 성능을 높이기 위해서는 Driving Table 의 크기가 작을수록 유리. Inner Table 은 조인되는 컬럼으로 인덱스가 구성되어 있어야 함.

선행(드라이빙) 테이블의 크기


NL 조인은 흔히 loop 문에 비교한다.

for(int i = 0 ; i < A.length; i++) { // 선행테이블
	for(int j = 0; j < B.length; j++) { // 후행테이블
	}
}

위 for 문을 예로 들어보면, 선행테이블인 A의 사이즈만큼 후행테이블을 조회하게 되는 것이다. 사실 이 예시까지 보고 들었던 의문이 있었다.

많은 책과 블로그들을 보면, 조인이 일어날 때 선행(드라이빙) 테이블의 크기를 줄여야 한다는 내용이 많다. 선행 테이블의 크기를 작게 하는 것이 SQL 성능에 유리하다는 것이다.

“for 문으로만 보았을 때 선행, 후행테이블의 순서를 서로 바꾼다고 하더라도 실제 반복문이 수행되는 횟수 자체는 줄어들지 않는데, A 테이블의 건수가 적을수록 유리하다는 건 왜일까?”

아마도 테이블에 access 하는 행위 자체도 부하가 일어나는 일이므로, 테이블에 접근하는 횟수 자체를 줄이는 것이 중요하기 때문으로 보인다. (이 부분은 조금 더 찾아보고 글을 더 보충하려고 한다.)

A. 위 그림에서 선행 테이블에 만족하는 행이 3건이고, 후행 테이블에 만족하는 행이 1000건이 있다고 가정해보면, 순차로 선행 테이블을 돌면서 후행 테이블에 3차례 접근한다.
B. 반면, 선행 테이블과 후행 테이블을 변경하는 경우, 순차로 테이블을 돌며 1000차례를 후행 테이블에 접근하게 될 것이다.

인덱스

그리고, 선행 테이블의 크기만큼 중요한 것은 ‘인덱스’ 여부이다.
후행 테이블에 인덱스가 없다고 하면, 크기가 큰 후행 테이블에 접근할 때 마다 table 전체를 full scan 하게 될 것이고, 그만큼 SQL 성능이 나오지 않는 결과를 초래한다.
따라서 선행 테이블의 크기를 줄이고, 후행 테이블에는 인덱스가 있는 것이 SQL 성능을 높이는 데 유리하다. (물론 둘 다 인덱스가 있으면 더 좋다)

NL 조인의 성능을 높이는 방법


따라서, NL 조인 성능을 높이는 공식은 흔히들 얘기하듯 아래처럼 정리할 수 있다.
1. 선행 테이블의 크기를 줄여 드리븐 테이블에 접근하는 횟수를 줄인다
2. 후행 테이블에 인덱스가 존재한다

물론 모든 케이스에서 다음과 같은 법칙이 항상 옳다고 할 순 없을 것이다.

* 만약, 후행 테이블 Join 컬럼에 인덱스가 존재하지 않는다면, Hash 또는 Merge Join 을 사용하여야 한다.
  
조금 더 이해를 돕기 위한 사이트 참고
http://ojc.asia/bbs/board.php?bo_table=LecHINT&wr_id=180

'공부 > DB' 카테고리의 다른 글

[SQL] ROWNUM 적용한 페이징 쿼리  (0) 2021.02.20
쿼리(LEAD)  (0) 2021.02.18
[SQL] ROWNUM = 2  (2) 2021.01.15
[SQL] Order by 문 변형  (0) 2021.01.15
오라클 튜닝  (0) 2019.09.22

댓글