홈 › 대용량·배치 › 01 / 8

실행 계획 읽기

EXPLAIN PLAN, EXPLAIN, 실행 계획 표시
섹션 6진행 0 / 8

2. 핵심 원리

2.1 예상 계획과 실제 실행 통계

실행 계획에는 두 종류가 있습니다. 예상 계획은 쿼리를 실행하지 않고 DB가 세운 계획만 보여 줍니다. 실제 실행 통계는 쿼리를 정말 실행하고 각 단계가 처리한 행 수와 시간을 함께 보여 줍니다.

구분 실행 여부 확인하는 것
예상 계획 실행 안 함 접근 방식, 예상 행 수
실제 실행 통계 실행함 예상 행 수와 실제 행 수, 시간

예상 계획은 안전하고 빠르므로 먼저 봅니다. 실제 실행 통계는 쿼리를 진짜 돌리므로 운영에서 무거운 쿼리나 변경 문장에는 조심해서 씁니다. INSERT, UPDATE, DELETE 에 실제 실행 명령을 쓰면 데이터가 바뀝니다.

2.2 DB별 실행 계획 명령

DB 예상 계획 실제 실행 통계
Oracle EXPLAIN PLAN FOR 문장 GATHER_PLAN_STATISTICS 힌트 후 DISPLAY_CURSOR
Tibero EXPLAIN PLAN, tbsql 의 SET AUTOTRACE 버전 확인
MySQL EXPLAIN 문장 EXPLAIN ANALYZE 문장(8.0.18 부터)
MSSQL SET SHOWPLAN_TEXT ON, SSMS 예상 계획 SSMS 실제 계획, SET STATISTICS PROFILE ON

Oracle 은 두 단계입니다. EXPLAIN PLAN FOR 문장; 으로 계획을 PLAN_TABLE 에 저장하고, SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY); 로 보기 좋게 꺼냅니다. SQL*Plus 에서는 SET AUTOTRACE 도 있습니다.

MySQL 은 문장 앞에 EXPLAIN 만 붙이면 표가 나옵니다. EXPLAIN FORMAT=TREE 는 8.0.16 부터 트리 모양으로 보여 주고, EXPLAIN ANALYZE 는 8.0.18 부터 실제로 실행해 시간과 행 수를 붙입니다. MSSQL 은 SSMS 그래픽 계획이 기본이고 텍스트로는 SET SHOWPLAN_TEXT ON 을 씁니다. 이 설정을 켜면 이후 문장은 실행되지 않고 계획만 나옵니다.

2.3 주요 연산 이름

DB마다 이름은 다르지만 접근 방식은 네 가지로 묶입니다.

접근 방식 Oracle MySQL type MSSQL
전체 읽기 TABLE ACCESS FULL ALL Table Scan(힙), Clustered Index Scan
키 한 건 INDEX UNIQUE SCAN const, eq_ref Index Seek, Clustered Index Seek
인덱스 범위 INDEX RANGE SCAN ref, range Index Seek
인덱스에서 테이블로 TABLE ACCESS BY INDEX ROWID (표 행 접근) Key Lookup

MySQL type 열은 좋은 순서로 const, eq_ref, ref, range, index, ALL 입니다. index 는 인덱스 전체를 훑는다는 뜻이라 ALL 보다는 낫지만 좁혀서 찾는 것은 아닙니다. Oracle 12c 부터는 TABLE ACCESS BY INDEX ROWID 가 BATCHED 로 표시되기도 합니다.

인덱스로 조건에 맞는 행을 찾고 나서 나머지 컬럼을 읽으러 테이블로 한 번 더 가는 단계가 있습니다. Oracle 은 ROWID 접근, MSSQL 은 Key Lookup 이라 부릅니다. 이 왕복이 많으면 인덱스를 써도 느려집니다.

2.4 계획을 읽는 순서

Oracle 의 표는 들여쓰기가 깊은 연산부터 실행되고, 깊이가 같으면 위에 있는 것부터 실행됩니다. 결과는 위로 올라가며 합쳐집니다. 그래서 표의 맨 아래쪽이 아니라 가장 안쪽에 들여쓴 줄에서 읽기 시작합니다.

MySQL 의 EXPLAIN 표는 id 가 큰 행이 먼저이고 id 가 같으면 위에서 아래입니다. MSSQL 텍스트 계획은 Oracle 처럼 들여쓴 트리라 안쪽부터 읽습니다. 그래픽 계획은 오른쪽에서 왼쪽으로 읽습니다.

2.5 예상 행 수와 실제 행 수

계획에서 가장 먼저 볼 숫자는 예상 행 수와 실제 행 수의 차이입니다. Oracle 의 E-Rows 와 A-Rows, MySQL EXPLAIN ANALYZE 의 rows 와 actual rows, MSSQL 그래픽 계획의 Estimated 와 Actual 이 그 짝입니다.

두 숫자가 크게 다르면 DB가 데이터 분포를 잘못 알고 있다는 뜻입니다. 이때는 인덱스를 더하기 전에 통계 정보를 의심합니다. 통계 갱신은 이 카테고리 04 레슨에서 다룹니다.

2.6 H2 EXPLAIN 으로 확인할 수 있는 것

H2 도 EXPLAIN 을 지원하지만 출력 형식이 실제 DB 와 완전히 다릅니다. H2 는 다시 쓴 SQL 아래에 /* PUBLIC.인덱스이름: 조건 */ 주석을 달고, 인덱스를 못 쓰면 tableScan 이라고 적습니다. 이 레슨은 그 주석에서 세 가지만 읽습니다.

H2 주석 뜻
테이블.tableScan 인덱스 없이 테이블 전체 읽기
인덱스: 조건 인덱스로 조건에 맞는 범위만 찾음
인덱스(조건 없음) 인덱스를 처음부터 끝까지 훑음