h1.09. Static vs. Dynamic SQl
- 하드 파싱을 최소화하기 위해 Dynamic SQL 대신 Static SQL 을 사용하라는 표현을 흔히 사용하는데,
용어를 제대로 사용하고 있는지 확인해 볼 필요가 있다. - 조건절에 바인드 변수를 사용하면 Static SQL, Literal 상수 값을 사용하면 Dynamic SQL 로 뷴류 하는
튜닝 교재들이 있어 이런 혼선이 빚어졌다고 생각한다*
h2.(1) Static SQL
- Static SQL 이란, String 형 변수(값을)를 담지 않고 코드 사이에 직접 기술한 SQL 문을 말한다.
다른 말로 'Embedded SQL' 이라고도 한다.
Init main()
\{
Printf("사번을 입력하시오 : ");
Scanf("%d",&empno);
EXEC SQL WHENEVER NOT FOUND GOTO notfound;
EXEC SQL SELECT ENAME INTO :ename
FROM EMP
WHERE EMPNO = :empno;
Printf("사원명 : %s.\n",ename);
Notfound:
Printf("%d는 존재하지 않는 사번입니다..\n",empno);
\}
- 여기서 보듯이 SQL 문을 String 변수에 담지 않고 마치 예약된 키워드처럼 C/C++ 코드 사이에 섞어서 기술하고 있다.
Static SQL 이든 Dynamic SQL 이든 PreCompile 단게를 거치고 나며 String 변수에
담기기는 마찬가지지만 Static SQL 은 런타임 시에 절대 변하지 않으므로 PreCompile 단계에서
구문 분석, 유효 오브젝트 여부, 오브젝트 액세스 권한 등을 체크하는 것이 가능하다.
h2.(2) Dynamic SQL
- Dynamic SQL 이란, String 형 변수에 담아서 기술하는 SQL문을 말한다.
String 변수를 사용하므로 조건에 따라 SQL 문을 동적으로 바꿀 수 있고,
또는 런타임 시에 사용자로부터 SQL문의 일부 또는 전부를 입력 받아서 실행 할 수도 있다.
따라서 PreCompile 시 Syntax, Semantics 체크가 불가능하다.
Int main()
\{
Char select_stmt\[50\] = "SELECT ENAME FROM EMP WHERE EMPNO = :empno";
// scanf("c", &select_stmt) ; ? SQL 문을 동적으로 입력 받을 수도 있음
EXEC SQL PREPARE sql_stmt FROM :select_stmt ;
EXEC SQL DECLARE emp_cursor CURSOR SQL sql_stmt ;
EXEC OPEN emp_cursor USING :empno ;
EXEC FETCH emp_cursor INTO :ename ;
EXEC CLOSE emp_cursor ;
Printf("사원명 : %s.\n", ename);
\}
- JAVA, Delphi, Visual Basic 에서는 Static SQL 을 작성할 수 있는 방법이 제공되지 않는다.
모두 String 변수에 담아서 실행하는 것이다. 따라서 이들 언어에서 작성된 SQL은 모두 Dynamic SQL 이다.
그런데도 Dynamic SQL 로 작성하지 말라고 한다면 어불성설이다. - Toad, Orange, SQL*PLUS 과 같은 ad-hoc 쿼리 툴에서 작성하는 SQL도
모두 Dynamic SQL 이라고 보면 틀림없다. - Statics(=embedded)SQL 을 지원하는 개발 언어로는 Powerbuilder, PL/SQL, Pro*C, SQLJ 정도가 있다.
h2.(3) 일반프로그램 언어에서 SQL 작성법
h2.(4) 문제의 본질은 바인드 변수 사용 여부 - 라이브러리 캐시 효율을 논할 때 초점은 바인드 변수 사용 여부에 맞춰져야 한다.
Dynamic SQL 을 사용해 문제가 되는 것이 아니라 바인드 변수를 사용하지 않았을 때 문제가 되는 것이다. - 바인드 변수를 사용하지 않고 Literal 값을 SQL 문자열에 결합하는 방식으로 개발했을 때,
반복적인 하드파싱으로 성능이 얼마나 저하되는지, 그리고 그 때문에 라이브러리 캐시에 얼마나 심한 경합이 발생하는지,
그 원리에 대해서는 앞에서 충분히 설명했다. - 다시 한번 강조하지만, 바인드 변수 사용 여부로 Static과 Dynamic 을 구분하는 것은 잘못된 것이므로 용어 사용에 주의하자.
h2.참고 )
1.http://www.gurubee.net/article/19612
([강정식의 오라클 이야기]Dynamic SQL 사용방법 )
No. | 구분 | STATIC | DYNAMIC |
1 | SQL 구성 | SQL을 CURSOR에 담아 사용 | SQL 을 CHAR 변수에 담아 만든 뒤 DBMS 에 완성된 SQL 구문을 날려서 데이터를 가져옴 |
2 | 개발 패턴 | STATICS SQL 은 SQL 모양이 변경되지 않아야 하기 때문에 일반적인 개발 패턴은 STATIC SQL 을 CURSOR 절에 선언한 뒤 이를 BEGIN END 절 사이에서 LOOPING 구조로 데이터를 처리하는 방식임 | DYNAMIC SQL 은 SQL 모양이 변경될 수 있기 때문에 NVL()처리를 할 필요가 없음. |
3 | 컬럼 구성 | STATIC SQL 은 정적이기 때문에 컬럼 또한 고정이 되어서 사용되어야 함 | DYNAMIC SQL은 구문을 변수에 담아서 DBMS를 콜하기 때문에 변수나 칼럼등 모든 SQL을 로직으로 처리하여 자유롭게 SQL구문을 만들 수 있음 |
4 | 실행 계획 | 옵티마이져는 NVL()처리가 되어있는 조건을 처리하기 위해 IS NULL, IS NOT NULL 로 나누어 실행게획을 세움, 만약 6개 조건이 있다면 12개의 CONCATEMATION 으로 실행계획이 쪼개져서 나오고 결국 실행 계획을 만들기 위한 하드파싱 시간이 오래 걸림 | 옵티마이져는 NVL()처리된 WHERE 조건이 없기 때문에 실행게획을 쪼깰 필요가 없고 그만큼 순수한 액세스 패스에 대해 실행계획을 작성하기 때문에 양호한 실행 계획이 작성되고 하드파싱 시간도 적어짐 |
- 결국 STATIC SQL 이라는 것은 고정된 SQL 형태를 만든 뒤에 이 SQL 형태로 모든 조건들을 처리해야 하는
- 반면, DYNAMIC SQL 은 여러 로직으로 조건에 해당되는 SQL을 변수에 담아서 만든 뒤에 DBMS를 콜하기 때문에 보다
풍부한 SQL을 작성할 수 있습니다. - 이처럼 DYNAMIC SQL 이 STATIC SQL 보다 여러 장점이 있는데로 불구하고 잘 사용되지 않는건 개발 난이도도
높고 개발시간도 현저히 늘어난다는 것입니다. 또한 STATIC SQL 이 직관적으로 볼 수 있는 반면 DYNAMIC SQL은
로직으로 SQL 을 만들어나가는 것이기 때문에 직관적이지 못하죠.