😗
SQL Guide
  • 😀SQL 전문가 가이드의 가이드
  • 😦과목1 데이터모델의 이해
    • ⭐제1장 데이터 모델링의 이해
      • 🌠1-1-1. 데이터 모델의 이해
      • 🌠1-1-2. 엔터티(Entity)
      • 🌠1-1-3. 속성(Attribute)
      • 🌠1-1-4. 관계(Relationship)
      • 🌠1-1-5. 식별자
    • ⭐제2장 데이터 모델과 SQL
      • 🌠1-2-1. 정규화
      • 🌠1-2-2. 관계와 조인의 이해
      • 🌠1-2-3. 모델이 표현하는 트랜잭션의 이해
      • 🌠1-2-4. Null 속성의 이해
      • 🌠1-2-5. 본질식별자 vs. 인조식별자
  • 😧과목2. SQL 기본과 활용
    • ⭐제1장 SQL 기본
      • 🌠2-1-1. 관계형 데이터베이스 개요
      • 🌠2-1-2. SELECT문
      • 🌠2-1-3. 함수(FUNCTION)
      • 🌠2-1-4. WHERE 절
      • 🌠2-1-5. GROUP BY, HAVING 절
      • 🌠2-1-6. ORDER BY 절
      • 🌠2-1-7. 조인
      • 🌠2-1-8. 표준 조인
    • ⭐제2장 SQL 활용
      • 🌠2-2-1. 서브 쿼리
      • 🌠2-2-2. 집합 연산자
      • 🌠2-2-3. 그룹 함수
      • 🌠2-2-4. 윈도우 함수
      • 🌠2-2-5. Top N 쿼리
      • 🌠2-2-6. 계층형 질의와 셀프 조인
      • 🌠2-2-7. PIVOT 절과 UNPIVOT 절
      • 🌠2-2-8. 정규 표현식
    • ⭐제3장 관리 구문
      • 🌠2-3-1. DML
      • 🌠2-3-2. TCL
      • 🌠2-3-3. DDL
      • 🌠2-3-4. DCL
  • 😨과목3. SQL 고급 활용 및 튜닝
    • ⭐제1장 SQL 수행 구조
      • 🌠3-1-1. 데이터베이스 아키텍처
      • 🌠3-1-2. SQL 처리 과정
      • 🌠3-1-3. 데이터베이스 I/O 메커니즘
    • ⭐제2장 SQL 분석 도구
      • 🌠3-2-1. 예상 실행계획
      • 🌠3-2-2. SQL 트레이스
      • 🌠3-2-3. 응답 시간 분석
    • ⭐제3장 인덱스 튜닝
      • 🌠3-3-1. 인덱스 기본 원리
      • 🌠3-3-2. 테이블 액세스 최소화
      • 🌠3-3-3. 인덱스 스캔 효율화
      • 🌠3-3-4. 인덱스 설계
    • ⭐제4장 조인 튜닝
      • 🌠3-4-1. NL 조인
      • 🌠3-4-2. 소트 머지 조인
      • 🌠3-4-3. 해시 조인
      • 🌠3-4-4. 스칼라 서브쿼리
      • 🌠3-4-5. 고급 조인 기법
    • ⭐제5장 SQL 옵티마이저
      • 🌠3-5-1. SQL 옵티마이징 원리
      • 🌠3-5-2. SQL 공유 및 재사용
      • 🌠3-5-3. 쿼리 변환
    • ⭐제6장 고급 SQL 튜닝
      • 🌠3-6-1. 소트 튜닝
      • 🌠3-6-2. DML 튜닝
      • 🌠3-6-3. 데이터베이스 Call 최소화
      • 🌠3-6-4. 파티셔닝
      • 🌠3-6-5. 대용량 배치 프로그램 튜닝
      • 🌠3-6-6. 고급 SQL 활용
    • ⭐제7장 Lock과 트랜잭션 동시성 제어
      • 🌠3-7-1. Lock
      • 🌠3-7-2. 트랜잭션
      • 🌠3-7-3. 동시성 제어
Powered by GitBook
On this page
  • 과목3. SQL 고급 활용 및 튜닝
  • 제4장 조인 튜닝
  • 제4절 스칼라 서브쿼리
  • 1. Scalar Subquery의 캐싱 효과 //TODO
  • 2. 두 개 이상의 값을 리턴하고 싶을때
  • 3. 스칼라 서브 쿼리 Unnesting //TODO

Was this helpful?

  1. 과목3. SQL 고급 활용 및 튜닝
  2. 제4장 조인 튜닝

3-4-4. 스칼라 서브쿼리

과목3. SQL 고급 활용 및 튜닝

제4장 조인 튜닝

제4절 스칼라 서브쿼리

쿼리에 내장된 또다른 쿼리 블록을 서브쿼리라고 하는데, 그 중에서 함수처럼 한 레코드당 정확히 하나의 값만을 리턴하는 서브쿼리를 'Scalar Subquery'라고 한다. Scalar Subquery는 주로 SELECT-list에서 사용되지만 몇 가지 예외사항을 뺀다면 칼럼이 올 수 있는 대부분 위치에서 사용 가능하다.

SELECT EMPNO
    , ENAME, SAL
    , HIREDATE
    , (SELECT D.DNAME
           FROM DEPT D
          WHERE D.DEPTNO = E.DEPTNO) dname
 FROM EMP E
WHERE SAL >= 2000 

Scalar Subquery를 사용한 위 쿼리 문장은 아래 Outer 조인문과 100% 같은 결과를 낸다. 즉 dept와 조인에 실패하는 emp 레코드가 있다면 dname으로 null 값이 출력된다.

SELECT /*+ ordered use_nl(d) */
      E.EMPNO, E.ENAME, E.SAL, E.HIREDATE, D.DNAME
 FROM EMP E
      RIGHT OUTER JOIN DEPT D
                    ON D.DEPTNO = E.DEPTNO
WHERE E.SAL >= 2000 

위에서 예시한 쿼리는 결과만 같은 것이 아니라 조인을 수행하는 처리 경로도 동일한데, NL 방식으로 수행되도록 힌트를 사용했기 때문이다. 다만 Scalar Subquery에는 내부적으로 캐싱 기법이 작용된다는 점이 다르고, 이를 이용한 튜닝이 자주 행해진다.

1. Scalar Subquery의 캐싱 효과 //TODO

2. 두 개 이상의 값을 리턴하고 싶을때

아래 쿼리는 위치가 'CHICAGO'인 부서(dept)만 대상으로 급여 수준을 집계하려는 것인데, 사원(emp) 테이블 전체를 다 읽어야 하는 비효율이 있다.

SELECT D.DEPTNO
    , D.DNAME
    , AVG_SAL
    , MIN_SAL
    , MAX_SAL
 FROM DEPT D
      RIGHT OUTER JOIN (SELECT DEPTNO
                               , AVG(SAL) avg_sal
                               , MIN(SAL) min_sal
                               , MAX(SAL) max_sal
                          FROM EMP
                         GROUP BY DEPTNO) E
                    ON E.DEPTNO = D.DEPTNO
WHERE D.LOC = 'CHICAGO' 

아래와 같이 바꿀 수 있으면 좋겠지만 스칼라 서브쿼리는 한 레코드당 하나의 값만 리턴한다는 특징 때문에 그럴 수가 없다.

SELECT D.DEPTNO
    , D.DNAME
    , (SELECT AVG(SAL)
                , MIN(SAL)
                , MAX(SAL)
           FROM EMP
          WHERE DEPTNO = D.DEPTNO)
 FROM DEPT D
WHERE D.LOC = 'CHICAGO' 

그렇다고 아래와 같이 쿼리한다면 emp에서 같은 범위를 반복적으로 액세스하는 비효율이 생긴다.

SELECT D.DEPTNO
    , D.DNAME
    , (SELECT AVG(SAL)
           FROM EMP
          WHERE DEPTNO = D.DEPTNO) avg_sal
    , (SELECT MIN(SAL)
           FROM EMP
          WHERE DEPTNO = D.DEPTNO) min_sal
    , (SELECT MAX(SAL)
           FROM EMP
          WHERE DEPTNO = D.DEPTNO) max_sal
 FROM DEPT D
WHERE D.LOC = 'CHICAGO' 

이럴 때, 아래 처럼 구하고자 하는 값들을 모두 결합하고서 바깥쪽 액세스 쿼리에서 substr 함수로 분리하는 방법이 유용하게 쓰인다.

[예제] Oracle

SELECT DEPTNO
    , DNAME
    , TO_NUMBER(SUBSTR(SAL, 1, 7)) avg_sal
    , TO_NUMBER(SUBSTR(SAL, 8, 7)) min_sal
    , TO_NUMBER(SUBSTR(SAL, 15))   max_sal
 FROM (SELECT D.DEPTNO
              , D.DNAME
              , (SELECT LPAD(AVG(SAL), 7)
                        || LPAD(MIN(SAL), 7)
                        || MAX(SAL)
                   FROM EMP
                  WHERE DEPTNO = D.DEPTNO) sal
         FROM DEPT D
        WHERE D.LOC = 'CHICAGO') 

[예제] SQL Server

SELECT DEPTNO
    , DNAME
    , CAST(SUBSTRING(SAL, 1, 7) AS FLOAT) avg_sal
    , CAST(SUBSTRING(SAL, 8, 7) AS INT)   min_sal
    , CAST(SUBSTRING(SAL, 15, 7) AS INT)  max_sal
 FROM (SELECT D.DEPTNO
              , D.DNAME
              , (SELECT STR(AVG(SAL), 7, 2) + STR(MIN(SAL), 7)
                        + STR(MAX(SAL), 7)
                   FROM EMP
                  WHERE DEPTNO = D.DEPTNO) sal
         FROM DEPT D
        WHERE D.LOC = 'CHICAGO') X 

3. 스칼라 서브 쿼리 Unnesting //TODO

Previous3-4-3. 해시 조인Next3-4-5. 고급 조인 기법

Last updated 3 years ago

Was this helpful?

출처 : 데이터온에어 – 한국데이터산업진흥원()

😨
⭐
🌠
https://dataonair.or.kr