-
Notifications
You must be signed in to change notification settings - Fork 0
2조 SQL JOIN
- Where 최적화
- Index 사용
- 메모리 설정
- Nested Loop Join
for each row in table1 (외부 루프)
for each row in table2 (내부 루프)
if join_condition is true
return joined_row
두 개의 중첩된 루프를 돌면서 순차적으로 JOIN 을 수행함 그림:
Table1 Table2
[A] → [1]
[B] → [2]
[C] → [3]
[4]
특징: 작은 테이블과 큰 테이블을 JOIN 할 때 효과적 적절한 인덱스가 있을 때 성능이 좋음 대규모 데이터 셋에서는 안좋은 성능을 보일 수도 ?
- Hash Join 작은 테이블로 해시 테이블을 생성 후 큰 테이블을 스캔하며 해시 테이블과 매칭하면서 JOIN 함 그림:
Probe Table Hash Function Hash Table Result
[A, data4] → Hash(A) = 1 → [1: (A, data1)] → [A, data1, data4]
[C, data5] → Hash(C) = 3 → [3: (C, data3)] → [C, data3, data5]
[D, data6] → Hash(D) = 4 → (No match) → (Excluded)
특징: 대규모 데이터셋에 효과적 동등 조인에 적합 범위 조인에 부적함 충분한 메모리가 필요
- Merge Join 정렬된 두 테이블을 병합하면서 JOIN을 수행 그림:
Table1 (Sorted) Table2 (Sorted)
[A] → [A]
[B] → [B]
[C] → [C]
[D]
특징: 이미 정렬된 데이터에 효과적 범위 조인에 적합 두 테이블을 순차적으로 읽기 때문에 I/O 효율이 좋다. 전체 테이블을 로드할 필요도 없어 메모리 효율성에서 좋다. 예시:
Table A
ID | Name
1 | Alice
3 | Charlie
4 | David
7 | George
Table B
ID | Name
1 | Alice
3 | Charlie
4 | David
7 | George
병합과정:
1. Table A의 ID 1과 Table B의 ID 2를 비교: 1 < 2, A 포인터 이동
2. Table A의 ID 3과 Table B의 ID 2를 비교: 3 > 2, B 포인터 이동
3. Table A의 ID 3과 Table B의 ID 3를 비교: 3 = 3, 매치! 결과에 추가
4. Table A의 ID 4와 Table B의 ID 4를 비교: 4 = 4, 매치! 결과에 추가
5. Table A의 ID 7과 Table B의 ID 5를 비교: 7 > 5, B 포인터 이동
6. Table B 끝에 도달, 종료
결과:
ID | Name | Age
3 | Charlie | 30
4 | David | 35
- I/O 비용
- CPU 비용
- 메모리 비용
- 네트워크 비용 이런 비용들은 일반적으로 행 수, 인덱스 사용 여부, 데이터 분포, 테이블 크기 등의 통계 정보를 기반으로 계산
a. 업데이트 주기: 자동 업데이트가 즉시 이루어지지 않을 수 있다.
b. 대규모 변경: 데이터의 급격한 변화를 즉시 반영하지 못할 수 있다.
c. 특정 작업: 일부 DDL 작업 후 통계가 자동으로 업데이트되지 않을 수 있다.
d. 샘플링: 자동 통계는 종종 샘플링을 기반으로 하므로, 완전히 정확하지 않을 수 있다.
자동 통계 업데이트를 활성화하되, 중요한 변경 후에는 수동으로 통계를 업데이트한다.
정기적으로 통계의 최신성을 확인하고 필요시 수동 업데이트를 수행한다.
성능 문제 해결 시 통계의 정확성을 항상 의심해보고 확인한다.
쿼리를 실행하기 위한 구체적인 절차를 설명하는 개념 EXPLAIN을 통해 확인이 가능하다.
EXPLAIN 명령어
실행 계획을 확인하여 비효율적인 작업을 식별
통계 정보 업데이트
테이블과 인덱스의 통계 정보를 최신으로 유지
옵티마이저가 정확한 비용을 추정할 수 있게 한다.
인덱스 최적화
실행 계획에서 테이블 풀 스캔이 발생하는 부분을 확인한다.
적절한 인덱스를 추가하여 데이터 접근 속도를 개선한다.
조인 순서 조정
실행 계획에서 비효율적인 조인 순서를 식별한다.
힌트를 사용하여 최적의 조인 순서를 지정한다.
조인 방식 변경
실행 계획에서 사용된 조인 방식(Nested Loop, Hash, Merge)을 확인.
데이터 특성에 맞는 조인 방식을 힌트로 지정.
서브쿼리 최적화
실행 계획에서 비효율적인 서브쿼리 처리를 찾는다.
조인으로 변환하거나 임시 테이블을 사용하여 최적화한다.
파티셔닝 활용
대용량 테이블에 대한 실행 계획을 분석한다.
파티셔닝을 통해 데이터 접근 범위를 줄인다.
작은 테이블을 드라이빙 테이블로 선택 드라이빙 테이블중 연산에 필요한 컬럼들의 데이터를 Join buffer에 저장 중간 결과 처리물이 join buffer보다 크면 디스크에 저장
Outer join을 사용하면 드라이빙 테이블을 최적의 테이블로 선별하기 어려움 Indexed nested loop join Block nested loop join
Oltp -> 대부분 nested loop join을 많이 사용한다. Olap
Hash join 문제점 : 해시 함수를 사용하기 때문에 cpu의 부하가 강해진다.