실행 계획이 만들어지면 DBMS는 그것을 바탕으로 데이터 접근을 수행한다. 그러나 여러 이유로 인해 SQL 실행이 지연될 수 있다.
이와 같이 지연이 발생했을 때는 가장 먼저 실행 계획을 살펴보아야 한다.
본 포스팅을 통해 간단하게 실행 계획의 핵심구성과 보는 방법에 대해 알아보자.
1. 실행 계획의 핵심구성
실행 계획에서 핵심적으로 봐야 하는 부분은 크게 다음의 3가지로 나뉜다.
1) 조작 대상 객체
- SQL 구문이 실행되는 과정에서 수행되는 조작(Operation)의 대상이 되는 객체를 의미한다
- 테이블 외에 인덱스, 파티션, 시퀀스처럼 SQL 구문으로 조작할 수 있는 객체라면 무엇이라도 올 수 있다
2) 객체에 대한 조작의 종류
- SQL 구문이 실행되는 과정에서 수행되는 조작(Operation)이 어떤 것인지를 의미한다
- 조작의 종류는 실행 계획에서 가장 중요한 부분이라고 할 수 있다
3) 조작 대상이 되는 레코드 수
- SQL 구문이 실행되는 과정에서 수행되는 조작(Operation)이 얼마만큼의 레코드에 대해 수행되는지를 의미한다
- 조작에서 처리되는 레코드의 수는 SQL 구문 전체의 실행 비용을 파악하는 데 중요한 지표가 된다
- 해당 레코드 수는 옵티마이저가 실행 계획을 만들 때 카탈로그로부터 얻는 값이다
- 즉, 해당 값은 통계 정보에 의한 것이므로 실제 SQL 구문을 실행한 시점과의 괴리가 존재하며, 절대 지표로 사용될 수 없다

2. DB별 실행 계획을 보는 방법
각 RDBMS별로 실행하는 명령어나 그 결과를 보여주는 방식에는 차이는 있지만, 핵심적인 내용은 동일하다.
이름 | 명령어 |
Oracle | set autotrace traceonly [SQL 구문] |
Microsoft SQL Server | SET SHOWPLAN_TEXT ON [SQL 구문] |
DB2 | EXPLAIN ALL WITH SNAPSHOT FOR [SQL 구문] |
PostgreSQL | EXPLAIN [SQL 구문] |
MySQL | EXPLAINT EXTENDED [SQL 구문] |
3. 실행 계획을 읽는 방법
다음과 같은 SQL 구문의 실행 계획을 살펴보면서 실행 계획을 읽는 방법에 대해 알아보자.
참고로 shop_id는 Shops 테이블의 PK이면서 Reservation 테이블의 FK이다.
SELECT shop_name
FROM Shops S
INNER JOIN Reservations R
ON S.shop_id = R.shop_id;
실행 계획은 일반적으로 트리 구조로 구성되어 있으며, 중첩 단계가 깊을수록 먼저 실행된다.
또한, 같은 중첩 단계에서는 위에서 아래로 실행된다.

따라서 위 실행 계획에 따르면 Reservation에 대한 접근이 먼저 일어난 뒤, Shop 테이블에 대한 접근이 이뤄진다. 그 후에 'Nested Loop' 방식으로 테이블이 결합되는 것을 확인할 수 있다.
4. 참조
- SQL 레벨업 (미크 저)
'CS > SQL' 카테고리의 다른 글
[MySQL] 하나의 글과 연관된 여러 개의 이미지 추출하는 쿼리 작성하기 (feat. GROUP_CONCAT) (0) | 2021.06.10 |
---|---|
[SQLD] SQLD 합격 후기 및 공부 방법 (6) | 2021.04.18 |
[MySQL] Connection Pool을 사용하는 이유 (0) | 2021.04.16 |
[SQLD] Join 연산 정리 (0) | 2021.03.18 |
[MySQL] MySQL에서 CSV파일 Import하기 (5) | 2021.02.10 |
실행 계획이 만들어지면 DBMS는 그것을 바탕으로 데이터 접근을 수행한다. 그러나 여러 이유로 인해 SQL 실행이 지연될 수 있다.
이와 같이 지연이 발생했을 때는 가장 먼저 실행 계획을 살펴보아야 한다.
본 포스팅을 통해 간단하게 실행 계획의 핵심구성과 보는 방법에 대해 알아보자.
1. 실행 계획의 핵심구성
실행 계획에서 핵심적으로 봐야 하는 부분은 크게 다음의 3가지로 나뉜다.
1) 조작 대상 객체
- SQL 구문이 실행되는 과정에서 수행되는 조작(Operation)의 대상이 되는 객체를 의미한다
- 테이블 외에 인덱스, 파티션, 시퀀스처럼 SQL 구문으로 조작할 수 있는 객체라면 무엇이라도 올 수 있다
2) 객체에 대한 조작의 종류
- SQL 구문이 실행되는 과정에서 수행되는 조작(Operation)이 어떤 것인지를 의미한다
- 조작의 종류는 실행 계획에서 가장 중요한 부분이라고 할 수 있다
3) 조작 대상이 되는 레코드 수
- SQL 구문이 실행되는 과정에서 수행되는 조작(Operation)이 얼마만큼의 레코드에 대해 수행되는지를 의미한다
- 조작에서 처리되는 레코드의 수는 SQL 구문 전체의 실행 비용을 파악하는 데 중요한 지표가 된다
- 해당 레코드 수는 옵티마이저가 실행 계획을 만들 때 카탈로그로부터 얻는 값이다
- 즉, 해당 값은 통계 정보에 의한 것이므로 실제 SQL 구문을 실행한 시점과의 괴리가 존재하며, 절대 지표로 사용될 수 없다

2. DB별 실행 계획을 보는 방법
각 RDBMS별로 실행하는 명령어나 그 결과를 보여주는 방식에는 차이는 있지만, 핵심적인 내용은 동일하다.
이름 | 명령어 |
Oracle | set autotrace traceonly [SQL 구문] |
Microsoft SQL Server | SET SHOWPLAN_TEXT ON [SQL 구문] |
DB2 | EXPLAIN ALL WITH SNAPSHOT FOR [SQL 구문] |
PostgreSQL | EXPLAIN [SQL 구문] |
MySQL | EXPLAINT EXTENDED [SQL 구문] |
3. 실행 계획을 읽는 방법
다음과 같은 SQL 구문의 실행 계획을 살펴보면서 실행 계획을 읽는 방법에 대해 알아보자.
참고로 shop_id는 Shops 테이블의 PK이면서 Reservation 테이블의 FK이다.
SELECT shop_name
FROM Shops S
INNER JOIN Reservations R
ON S.shop_id = R.shop_id;
실행 계획은 일반적으로 트리 구조로 구성되어 있으며, 중첩 단계가 깊을수록 먼저 실행된다.
또한, 같은 중첩 단계에서는 위에서 아래로 실행된다.

따라서 위 실행 계획에 따르면 Reservation에 대한 접근이 먼저 일어난 뒤, Shop 테이블에 대한 접근이 이뤄진다. 그 후에 'Nested Loop' 방식으로 테이블이 결합되는 것을 확인할 수 있다.
4. 참조
- SQL 레벨업 (미크 저)
'CS > SQL' 카테고리의 다른 글
[MySQL] 하나의 글과 연관된 여러 개의 이미지 추출하는 쿼리 작성하기 (feat. GROUP_CONCAT) (0) | 2021.06.10 |
---|---|
[SQLD] SQLD 합격 후기 및 공부 방법 (6) | 2021.04.18 |
[MySQL] Connection Pool을 사용하는 이유 (0) | 2021.04.16 |
[SQLD] Join 연산 정리 (0) | 2021.03.18 |
[MySQL] MySQL에서 CSV파일 Import하기 (5) | 2021.02.10 |