문서유형ㅣ기술정보
분야ㅣ튜닝
적용제품버전ㅣTibero4 이상
문서번호ㅣTTUTI033
개요
SQL에서 리터럴(Literal) 과 바인드 변수(Bind Variable) 의 개념과 차이를 설명합니다.
방법
1. 리터럴(Literal) SQL이란?
WHERE 절의 비교 값에 문자/숫자 상수 값을 직접 하드코딩하여 작성한 SQL문을 의미합니다.
SELECT * FROM EMP WHERE EMPNO = 100;
이처럼 매번 다른 값이 들어가면 서버는 매번 새로운 SQL로 인식하여 하드 파싱(Hard Parsing)을 수행합니다.
2. 바인드 변수(Bind Variable) SQL이란?
WHERE 절의 특정 값을 바인드 변수(:B) 형태로 지정하여 값만 실행 시점에 전달하는 방식입니다..
SELECT * FROM EMP WHERE EMPNO =:B1;
바인드 변수를 사용하면 같은 SQL 문장으로 인식되어 소프트 파싱(Soft Parsing) 이 가능해지고,
Library Cache 재사용률이 높아져 성능 향상에 도움이 됩니다.
3. 파싱(Parsing)의 종류
🔹 Hard Parsing
- SQL 문장이 Shared Pool / Library Cache에 없을 때 수행됩니다.
- SQL의 문법(Syntax), 테이블 및 칼럼 존재 여부, 권한 등을 Dictionary Cache를 이용해 검사합니다.
- CPU 사용량이 많으며, Spin Lock 경합이 증가합니다.
🔹 Soft Parsing
- 이미 Shared Pool에 동일한 SQL 문장이 존재할 때 수행됩니다.
- 기존의 파싱 트리(Parsing Tree)와 실행 계획을 그대로 재사용합니다.
- 같은 SQL을 재실행할수록 성능이 향상됩니다.
4. 하드 파싱이 발생하는 경우
아래와 같은 경우에는 동일한 의미라도 서로 다른 SQL로 인식되어 하드 파싱이 발생합니다.
| 구분 | 설명 |
|---|---|
| 스키마 다름 | 스키마가 다르면 다른 SQL로 인식 |
| 공백 다름 | 공백 차이도 별개 SQL |
| 줄바꿈 다름 | 줄 위치가 다르면 다른 SQL |
| 대소문자 다름 | 대소문자 구분됨 |
실습 예제
실습 1: 리터럴 SQL 실행
CREATE TABLE EMP1(EMPNO NUMBER, ENAME VARCHAR(20));
INSERT INTO EMP1 SELECT LEVEL, 'TIBERO' || LEVEL FROM DUAL CONNECT BY LEVEL <= 5;
INSERT INTO EMP1 SELECT LEVEL, 'TIBERO' || LEVEL FROM DUAL CONNECT BY LEVEL <= 3;
COMMIT;
ALTER SYSTEM FLUSH SHARED_POOL;
DECLARE
v_sql VARCHAR2(500);
v_cnt NUMBER;
BEGIN
FOR i IN 1..5 LOOP
v_sql := 'SELECT /* LITERAL001 */ COUNT(*) FROM EMP1 WHERE EMPNO = ' || i;
DBMS_OUTPUT.PUT_LINE(v_sql);
EXECUTE IMMEDIATE v_sql INTO v_cnt;
DBMS_OUTPUT.PUT_LINE(v_cnt);
END LOOP;
END;
/결과:
각 쿼리가 EMPNO 값에 따라 모두 다르게 인식되어 5개의 서로 다른 SQL로 하드 파싱됩니다.
실습 2: V$SQLAREA에서 리터럴 SQL 확인
SELECT SUBSTR(sql_text,1,200) AS SQL, COUNT(*), SUM(EXECUTIONS) FROM V$SQLAREA WHERE SQL_TEXT LIKE 'SELECT /* LITERAL001%' GROUP BY SUBSTR(sql_text,1,200) ORDER BY COUNT(*);
결과:
WHERE EMPNO = 1, 2, 3, ... 각각 COUNT(*) = 1
→ 동일한 SQL이 아님을 확인합니다. (하드 파싱 발생)
실습 3: 바인드 변수 SQL 실행
DECLARE
v_sql VARCHAR2(100);
v_cnt NUMBER;
BEGIN
FOR i IN 1..5 LOOP
v_sql := 'SELECT /* BIND001 */ COUNT(*) FROM EMP1 WHERE EMPNO = :i';
DBMS_OUTPUT.PUT_LINE(v_sql || ' <---- ' || i);
EXECUTE IMMEDIATE v_sql INTO v_cnt USING i;
DBMS_OUTPUT.PUT_LINE(v_cnt);
END LOOP;
END;
/결과:
모든 SQL이 동일한 문장으로 인식되어 파싱은 1회, 실행은 5회 수행됩니다.
실습 4: V$SQLAREA에서 바인드 변수 SQL 확인
SELECT SUBSTR(sql_text,1,200) AS SQL, COUNT(*), SUM(EXECUTIONS) FROM V$SQLAREA WHERE SQL_TEXT LIKE 'SELECT /* BIND001%' GROUP BY SUBSTR(sql_text,1,200) ORDER BY 2;
결과:
COUNT(*) = 1, SUM(EXECUTIONS) = 5
→ 동일 SQL로 인식되어 소프트 파싱이 발생합니다.
정리 요약
| 구분 | 리터럴(Literal) SQL | 바인드 변수(Bind Variable) SQL |
|---|---|---|
| 값 처리 방식 | 값 직접 하드코딩 | 바인드 변수로 전달 |
| SQL 인식 | 매번 다른 SQL로 인식 | 동일한 SQL로 인식 |
| 파싱 방식 | 하드 파싱 (Hard Parsing) | 소프트 파싱 (Soft Parsing) |
| 캐시 활용 | 낮음 | 높음 |
| 성능 | 느림 (CPU 부하, Spin Lock 증가) | 빠름 (재사용 효율 ↑) |
참고 용어
※ Shared Pool / Library Cache : SQL 문장, 실행계획, PL/SQL 등을 저장해 재사용하는 메모리 영역
※ Dictionary Cache : 객체, 사용자, 권한 등의 메타데이터를 저장하는 캐시
※ Spin Lock : SGA 내부 자원에 대한 배타적 접근을 제어하는 가벼운 락(Lock)
※ SGA (System Global Area) : DB 인스턴스 전체가 공유하는 메모리 구조
※ Hard Parsing : 새 SQL 문장을 처음 파싱하여 캐시에 저장하는 과정
※ Soft Parsing : 기존 캐시에 존재하는 SQL을 재활용하는 과정