6. 결합(결합을 지배하는 자가 SQL을 지배한다)

ch 18. 기능적인 관점으로 구분하는 결합의 종류

  • 크로스 결합
  • 내부 결합
  • 외부 결합
  • 자기 결합
  • 등가 결합/비등가 결합
  • 자연 결합
  • 위에서 3개는 배타적 결합이다.
  • 컬럼) 자연 결합 구문
    • 자연결합 = 내부 결합 + 등가 결합

1) 크로스 결합 - 모든 결합의 모체

  • 데카르트 곱

(1) 실무에서 사용하지 않음

  • 그런 결과가 필요없다
  • 비용이 크다

(2) 실수로 사용한 크로스 결합

  • SELECT * FROM Employees, Departments;

2) 내부 결합 - 왜 ‘내부’라는 말을 사용할까?

(1) 내부 결합의 작용

  • 크로스 결합 결과의 부분집합

(2) 내부 결합과 같은 기능을 하는 상관 서브쿼리

  • 스칼라 서브쿼리 = 리턴값이 하나인쿼리(SELECT의 필요 조건)
  • 상관 서브쿼리보다 결합이 우수하다

3) 외부 결합 - 왜 ‘외부’라는 말을 사용할까?

(1) 외부 결합의 작동

  • 왼쪽/오른쪽/완전 외부 결합
  • 키를 모두 가진 레이아웃의 리포트를 만들때 사용

4) 외부 결합과 내부 결합의 차이

  • 외부 결합은 NULL을 생성한다

5) 자기 결합 - ‘자기’란 누구일까?

ch 19. 결합 알고리즘과 성능

  • Nested Loops
  • Hash
  • Sort Merge

1) Nested Loops

  • 이중 반복
  • 바깥 반복 테이블(구동 테이블, 외부 테이블) <-> 내부 테이블
  • 접근하는 레코드 수 R(A) * R(B)이며 실행 시간은 레코드수에 비례한다.
  • 구동 테이블을 작게 만드는 것이 중요하다

(1) 구동 테이블의 중요성

  • (내부 테이블의 결합키 필드에 인덱스가 존재) 구동 테이블을 작게
  • 내부 테이블의 반복을 줄일 수 있음
  • 이상적으로 구동 테이블의 레코드 한개에 내부 테이블의 레코드 한개가 대응하고, 해당 레코드를 내부 테이블의 인덱스로 사용해 찾을 수 있는 경우 레코드 레코드 수는 R(A) * 2

(2) Nested Loops 의 단점

  • 결합키로 내부 테이블에 접근할 때 히트되는 레코드가 너무 많기 때문이다.
  • 해결
      1. 역설적이게 구동 테이블을 큰것으로
      1. Hash

2) Hash

(1) Hash의 작동

  • 작은 테이블을 스캔해 결합키 Hash (워키 메모리 사용량을 줄이기 위해)
  • 큰 테이블에 접근해 Hash하고 매칭

(2) Hash의 특징

  • 결합 테이블로부터 해시 테이블을 만드므로 Nested Loops에 비해 메모리를 많이 사용
  • 메모리가 부족하면 저장소 사용으로 지연
  • 출력되는 해시값은 입력값의 순서를 알지 못하므로, 등치 결합에만 사용 가능

(3) Hash가 유용한 경우

  • Nested Loops에서 적절한 구동 테이블이 존재하지 않는 경우
  • 적절한 구동 테이블이 있지만, 내부 테이블에서 히트되는 레코드 수가 많은 경우
  • Nested Loops의 내부 테이블에 인덱스가 존재하지 않는 경우

(4) 유의사항

  • OLTP에서는 사용하면 안된다.
  • 풀스캔(해시를 위해)의 비용도 고려할 것

3) Sort Merge

(1) Sort Merge의 작동

  • 결합키로 테이블들을 정렬하고, 일치하는 것 끼리 결합
  • 대상 테이블을 모두 정렬해야하므로 메모리가 많이 사용
  • Hash와 달리 부등호를 사용해 결합 가능
  • 테이블이 정렬되어 있다면 정렬을 생략 가능
  • 테이블을 정렬하므로 테이블을 모두 스캔한 시점에 결합 완료

(2) Sort Meger가 유효한 경우

  • 테이블 정렬을 생략 가능한 경우

4) 의도하지 않은 크로스 결합

  • 삼각 결합 : 결합 조건이 A-B, A-C인 경우
  • B-C 사이에 크로스 결합이 일어날 수 있다. 옵티마이저가 B,C의 크기가 충분히 작다고 판단하는 경우

(1) 의도하지 않은 크로스 결합을 회피하는 방법

  • 불필요한 결합 조건 추가

ch 20. 결합이 느리다면