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.구분STATICDYNAMIC
1SQL 구성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 을 만들어나가는 것이기 때문에 직관적이지 못하죠.