-
[SQL] SUB QUERYData miner/Development log 2023. 4. 6. 16:11728x90
서브 쿼리의 종류
- 서브쿼리는 QUERY OF QUERY 로 메인 쿼리의 각 부분 파트에 또 다른 쿼리문이 있는 형태다. 별도로 괄호로 묶은 쿼리 블록으로 표현된다. SQL 옵티마이저는 서브쿼리를 참조하는 메인 쿼리 블록을 포함하여, 쿼리 블록 단위로 쿼리 최적화를 수행한다.
1) SELECT 문에 SUB QUERY가 있는 경우
- 스칼라 서브쿼리라고 불림
- 하나의 레코드 당 하나의 값을 반환하는 서브 쿼리
- 주의할 점 : 데이터 양이 많으면, 실행속도가 느려짐
2) FROM 문에 SUB QUERY가 있는 경우
- 테이블 처럼 사용됨. 인라인뷰 서브쿼리라고 불림
ex)
SELECT c.고객번호, c.고객명 FROM 고객테이블 c, (SELECT 고객번호, avg(거래금액) 평균거래 ,min(거래금액) 최소거래, max(거래금액) 최대거래 FROM 거래테이블 WEHRE 거래날짜 >= trnc(sysdate, 'mm') GROUPBY 고객번호) t WHERE c.가입일시 >= trnc(add_months(sysdate, -1), 'mm') AND t.고객번호 = c.고객번호
3) WHERE 문에 SUB QUERY가 있는 경우
- 결과 집합을 한정하기 위해 WHERE 절에 사용한 서브 쿼리
- 서브 쿼리가 메인 쿼리를 참조한다면, 상관관계(Corelated) 서브 쿼리라고 함
SELECT c.고객번호, c.고객명 FROM 고객테이블 c WHERE c.가입일시 >= trunc(add_months(sysdate, -1), 'mm') and exists (SELECT 'x' FROM 고객변경이력 h WHERE h.고객번호 = c.고객번호 and h.변경사유코드 = 'zbc')
서브쿼리와 조인
- 메인 쿼리와 서브 쿼리 간에는 부모와 자식이라는 종속적이고 계층적인 관계가 존재. 서브쿼리는 메인쿼리에 종속되므로 단독으로 실행할 수 없음
필터오퍼레이션
SELECT c.고객번호, c.고객명 FROM 고객테이블 c, WHERE c.가입일시 >= trnc(add_months(sysdate, -1), 'mm') AND exists (SELECT /*+ no_unnest */ 'x' from 거래정보 t where t.고객번호 = c.고객번호 and t.거래일시 >= trunc(sysdate, 'mm'))
- /*+ no_unnest */ 힌트 사용
- 기본적으로 NL 조인과 처리 루틴이 같음.
1) 다만, 메인쿼리(고객)의 한 로우가 서브쿼리(거래)의 한 로우와 조인에 성공하면 탐색 진행을 멈추고(inner loop exit), 메인쿼리의 다음 로우를 계속 처리함
2) 메인쿼리 결과집합이 서브쿼리 결과집합으로 확장되어 고객정보가 중복되는 현상을 막을 수 있음
- NL조인과 다른 점은 이 필터 기능이 캐싱기능을 가짐. 서브쿼리 입력값에 대한 반환값(T/F)를 가져서 서브쿼리를 수행하기 전에 캐시부터 확인함
- 필터 서브쿼리는 메인 쿼리에 종속되며, 메인쿼리가 드라이빙 집합인 순서로 조인 순서가 고정됨
서브쿼리 Unnesting
- 중첩구조를 포개넣지 않는다 (unnest). 중첩구조를 풀어낸다는 의미. 즉, 메인쿼리와 서브쿼리의 계층적인 상태가 아닌 두 쿼리를 동일선상에서 처리하겠다는 뜻
- 서브쿼리를 메인쿼리와 같은 계층에 넣게 되면, 서브쿼리 쪽 집합 수준으로 확장되지 않게 유의해야 한다.
- unnesting되지 않은 서브쿼리는 위의 필터 방식으로 항상 처리 됨
서브쿼리 Pushing
- Unnesting되지 않은 서브쿼리에 한해, 서브쿼리 필터링 가능한 한 앞단계에서 강제
- push_subq/no_push_subq 힌트를 사용, no_unnest힌트와 함께 사용한다
ex) /*+ no_unnest push_subq */
*sysdate - 현재날짜와 시간 정보 알려줌
*trunc('2023-04-05 00:00:00', 'mm') - '월'만 추출
'Data miner > Development log' 카테고리의 다른 글
[SQL] JOIN TUNING / NL JOIN (0) 2023.04.03 [parquet] 파일 나눠서 저장하기 (0) 2023.03.25 [torch] torch.einsum 함수 이해하기 (1) 2022.11.15 [Spark] [python] Spark Application (0) 2021.03.05 [Spark] [python] 구조적 API 기본 연산 (0) 2021.03.01