SQL의 실행과정

2025. 5. 27. 22:00·CS 스터디/CS - DB

SQL이란


먼저 SQL이란, Structured Query Language의 줄임말로 관계형 데이터베이스(RDBMS)에서 데이터를 CRUD할 수 있게 해주는 표준 프로그래밍 언어입니다. 쉽게 말해, 데이터베이스에서 데이터를 다루기 위한 언어라고 할 수 있습니다.

 

SQL의 실행과정은 크게 파싱 → 최적화 → 로우소스 생성 → 실행 순입니다. 순서대로 살펴보겠습니다.

 

1. 파싱 (Parsing)


파싱은 SQL의 가장 첫 번째 실행단계로, 사용자가 입력한 SQL문을 분석하여 구문 및 의미를 확인하는 단계입니다.

파싱의 단계

1. 문법 체크 (Syntax Check)

  • 쿼리문 즉, 실행한 SQL 명령에 대해 문법의 오류나 오타가 있는지 확인하는 단계
  • 문법적으로 올바르지 않은 경우 오류를 반환합니다.

2. 의미 & 권한 체크 (Semantic Check)

  • 문법이 맞았다면, 문법이 선언될 데이터베이스의 테이블 명, 컬럼 명 등이 데이터베이스에 존재하는지, 해당 테이블을 읽을 수 있는지 권한을 확인하는 단계
  • 딕셔너리 캐시를 통해 확인합니다.

라이브러리 캐시 체크 (Library Cache Check)

  • 라이브러리 캐시 체크를 통해 하드 파싱, 소프트 파싱으로 나뉩니다.
  • 동일한 SQL문이 있다면 이전 실행계획을 재사용하여 바로 실행단계로 넘어가는 소프트 파싱 수행
  • SQL 문이 처음 실행되거나 동일 SQL문의 기존 실행 계획을 재사용할 수 없을 때 하드 파싱 수행

 

2. 최적화 (Optimization)


SQL문의 최적화된 실행 계획을 생성하는 단계입니다.

 

하드 파싱시에만 해당 데이터베이스의 통계정보를 바탕으로 시뮬레이션을 수행하는 Estimator가 가장 효율적인 실행 계획을 선택합니다.

최적화의 단계

1. 쿼리 변환 (Query Transformation)

  • 옵티마이저가 SQL을 더 효율적으로 실행할 수 있는 형태로 변환하는 단계
  • 대표적으로 불필요한 조건 제거, 서브쿼리 변환, 조인 순서 변경, 데이터 접근 방식 변경 등을 수행

1.1 불필요한 조건 제거

SELECT * FROM users WHERE age > 10 AND age > 20; -- 조건 중복
-- 옵티마이저가 중복되는 조건을 제거 시
SELECT * FROM users WHERE age > 20;

 

1.2 서브쿼리 변환

SELECT * FROM employees 
WHERE dept_id 
IN (SELECT dept_id FROM departments WHERE name = 'IT'); -- 서브쿼리 연산 (성능 저하)
-- 옵티마이저가 서브쿼리 -> 조인연산으로 변경 시
SELECT e.* FROM employees e 
JOIN departments d 
ON e.dept_id = d.dept_id WHERE d.name = 'IT';

 

1.3 조인 순서 변경

SELECT *
FROM employees e
JOIN departments d ON e.dept_id = d.dept_id
WHERE d.name = 'IT'; -- WHERE 조건 절 필터링 테이블과 대상(FROM) 테이블이 다름
-- 옵티마이저가 조인 순서 변경 시
SELECT *
FROM departments d
JOIN employees e ON e.dept_id = d.dept_id
WHERE d.name = 'IT';

 

1.4 데이터 접근 방식 변경

-- 기존 쿼리 -> 테이블의 전체 행을 찾는 Full Table Scan 방식
SELECT * FROM customers WHERE status = 'inactive';

-- 옵티마이저가 데이터 접근 방식 변경 시 -> 테이블에 인덱스가 존재하는 경우 인덱스 접근방식으로 변경

-- 인덱스 접근방식으로 변경
SELECT * FROM customers WHERE status = 'inactive' USE INDEX (idx_status);
더보기
❓Full Table Scan / Index Scan
Full Table Scan : 테이블의 모든 행을 하나씩 조회하는 방법 (전체 탐색 방식)
Index Scan : 특정 컬럼의 인덱스를 이용해 빠르게 조회하는 방법 (색인 탐색 방식)
일반적으로 Index Scan이 Full Table Scan 보다 빠른 탐색 속도를 보장합니다.

2. 실행 계획 생성 (Plan Generation)

  • 쿼리 변환을 거치면서 변환된 SQL을 기반으로 여러 실행 계획을 생성하는 단계

3. 비용 계산 및 실행 계획 선택 (Cost Estimation)

  • 가장 낮은 비용을 선택하여 실제로 실행할 계획을 선택하는 단계
  • 각 생성된 실행 계획의 CPU 사용량 + I/O 비용 + 네트워크 비용 등을 시뮬레이션을 통해 비용을 계산
더보기
💡 옵티마이저는 항상 최적의 경로를 선택하는가?
옵티마이저가 항상 가장 좋은 경로를 선택하는 건 아닙니다. 그 이유로는 다양한 원인이 존재합니다.
1. 통계 정보 부정확 - 해당 데이터베이스에서 수집된 통계정보가 오래된 경우일 수 있습니다.
2. 복잡한 쿼리 구조 - 최적의 계획을 찾기 위한 모든 조합을 탐색하면 시간이 너무 오래 걸리므로 부분 탐색으로 타협
3. 제한된 힌트나 강제된 계획 - 사용자의 실행 계획 고정
4. 비용 기반 계산의 맹점 - 옵티마이저는 실행 비용을 바탕으로 실행 계획을 수립하지만 이 비용은 절대적인 속도와 다를 수 있음

 

3. 로우소스 생성 (Row Source Generation)


최적의 경로로 선택된 SQL문을 실제로 실행하기 위해 데이터베이스 엔진이 읽을 수 있도록 처리하는 단계

 

데이터베이스 엔진이 실제로 처리할 수 있는 실행 가능한 코드(프로시저)를 생성합니다.

이 과정에서 로우 소스 트리가 만들어지며 SQL 문법 실행 순서에 기반해 병목구간을 찾고, 실행 시간을 최적화 합니다.

 

< SQL의 실행 흐름 계획을 로우 소스 트리 형태로 시각화한 예시 >

SELECT e.ename, d.dname
FROM emp e
JOIN dept d ON e.deptno = d.deptno
WHERE e.sal > 3000
ORDER BY e.ename;

-- 로우 소스 트리의 시각화 -> 각 로우소스를 기반으로 데이터를 처리하는 순서 정의
-- 실행 순서는 Id역순으로 실행 즉, 0번이 가장 마지막으로 실행
--------------------------------------------------------------------------------
| Id  | Operation          | Name  | Rows  | Bytes | Cost (%CPU) | Time     |
--------------------------------------------------------------------------------
|   0 |SELECT STATEMENT    |       |   10  |  250  |  500 (80%)  |  00:00:10|
|   1 | SORT ORDER BY      |       |   10  |  250  |  200 (50%)  |  00:00:05|
|   2 |  HASH JOIN         |       |   10  |  250  |  300 (60%)  |  00:00:06|
|   3 |   TABLE ACCESS FULL| EMP   |   10  |  150  |  250 (70%)  |  00:00:07|
|   4 |   TABLE ACCESS FULL| DEPT  |    5  |  100  |  50  (30%)  |  00:00:02|
--------------------------------------------------------------------------------
더보기
⚙️ SQL의 실행의 논리적 순서
FROM ➡️ ON ➡️ JOIN ➡️ WHERE ➡️ GROUP BY ➡️ HAVING ➡️ SELECT ➡️ ORDER BY
해당 논리적 순서는 SQL의 결과를 가져오기 위한 논리적 흐름으로, 우선순위가 아니라 처리의 당연한 순서일 뿐입니다.
로우 소스 트리는 실제 쿼리 처리 과정을 담고 있으므로, 위의 실행 계획에서 SELECT가 ORDER BY보다 나중에 나타나는 것에 대해 혼동하지 않도록 주의가 필요합니다.
실제 실행 계획에서 SELECT는 실행 결과를 받아 출력하는 루트 컨테이너 역할이라고 이해하면 됩니다.

 

4. 실행 (Execution)


로우 소스로 변경된 SQL문을 로우소스 생성기가 만든 로우 소스 트리를 따라 순차적으로 데이터를 검색 및 처리하고, 처리된 데이터를 클라이언트에게 실제로 반환(Fetch)하는 단계

 

로우 소스 트리는 SQL의 실행 계획을 트리 구조로 나타낸 것 입니다. 아래의 트리 그림은 위에서 예시로 들었던 로우 소스 트리를 트리구조로 나타낸 것 입니다.

아래쪽 노드는 데이터 생성자 (ex. 테이블에서 행을 읽음) / 위쪽 노드는 데이터 소비자 (ex. 조인, 정렬, 필터링) 입니다.

따라서 실행 엔진은 클라이언트에게 결과를 반환하기 위해, 로우 소스 트리의 하위 연산자부터 데이터를 읽고 상위 연산자에게 전달하며 순차적으로 처리합니다.

-- 로우 소스 트리 (트리 구조로 표현)
      SELECT (0)
        ↑
      SORT (1)
        ↑
    HASH JOIN (2)
     ↑       ↑
EMP(3)     DEPT(4)

 

🔎 EXPLAIN 키워드


EXPLAIN은 SQL문을 실행하지 않고, 옵티마이저의 실행 계획을 확인할 수 있는 명령어입니다.
-- MySQL 기준 경로 확인 방법 : 쿼리문 앞에 EXPLAIN 명령어 사용
EXPLAIN SELECT *
FROM customers
WHERE status = 'inactive';

위와 같이 EXPLAIN 키워드를 활용하여 옵티마이저의 최종 실행 계획을 확인할 수 있습니다. 또한 EXPLAIN으로 실행 계획을 확인 했을때, 옵티마이저가 최적의 실행계획을 수립하지 않은 경우에 힌트를 활용하여 실행 계획을 강제할 수 있습니다.

 

아래는 힌트를 사용하여 기존의 실행 계획을 강제하는 예시입니다.

-- 기존 쿼리의 실행 계획
SELECT * FROM customers WHERE status = 'inactive';

-- 옵티마이저가 예상과 달리 풀 테이블 스캔을 선택하는 경우 아래와 같이 힌트 적용 가능
SELECT /*+ INDEX(customers idx_status) */
*
FROM customers
WHERE status = 'inactive';

 

하지만, 데이터는 항상 변경될 수 있고, 힌트는 경로를 제한하기 때문에, 대규모 데이터의 성능 튜닝같은 특정한 경우를 제외하고는 권장되지 않는 방법입니다.

 

'CS 스터디 > CS - DB' 카테고리의 다른 글

데이터베이스 Key의 개념과 종류  (0) 2025.07.07
데이터베이스  (0) 2025.05.18
'CS 스터디/CS - DB' 카테고리의 다른 글
  • 데이터베이스 Key의 개념과 종류
  • 데이터베이스
BIS's tech Blog
BIS's tech Blog
Welcome to Kanghyun's tech blog :)
  • BIS's tech Blog
    벼익숙의 기술 블로그
    BIS's tech Blog
  • 전체
    오늘
    어제
    • 분류 전체보기 (63) N
      • 알고리즘 (49) N
        • 백준 (40) N
        • 프로그래머스 (9)
      • CS 스터디 (14)
        • CS - JAVA (11)
        • CS - DB (3)
      • Spring (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • GitHub
  • 공지사항

  • 인기 글

  • 태그

    dp
    깊이 우선 탐색
    백준
    DFS
    java
    재귀
    bottom-up
    BFS
    브루트포스
    Top-Down
    CS
    완전탐색
    자료구조
    알고리즘 고득점 kit
    프로그래머스
    기술질문
    너비 우선 탐색
    동적 계획
    Baekjoon
    Lv2
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
BIS's tech Blog
SQL의 실행과정
상단으로

티스토리툴바