1. Static SQL을 지원하는 개발 환경에서는 Static SQL을 사용하는 것을 원칙으로 한다.
2. 아래와 같은 경우에는 Dynamic SQL을 사용할 수도 있다.
3. 2번 경우에 해당해서 Dynamic SQL를 사용하더라도 조건절에는 바인드 변수를 사용하는 것을 원칙으로 한다
4. 3번 바인드 변수 사용원칙을 준수하되 아래 경우는 예외적으로 인정한다.
Static SQL : SQL Repository에 완성된 형태로 저장한 SQL
Dynamic SQL : SQL Repository에 불완전한 형태로 저장한 후 런타임 시 상황과 조건에 따라 동적으로 생성되도록 작성한 SQL
select 거래일자, 종목코드, 투자자유형코드, 주문매체코드
, 체결건수,체결수량, 거래대금
from 일별종목거 래
where 거래일자 between 시작일자 and 종료일자
%option
%option = " and 종목코드 = 'KR123456' and 투자자유형코드 = '1000' "
조건에 따라 실행계획이 변경, 라이브러리 캐시를 비효율적으로 사용하여 하드파싱이 빈번히 일어 남
select 거래일자, 종목코드, 투자자유형코드, 주문매체코드
, 체결건수, 체결수량, 거래대금
from 일별종목거래
where 거래일자 between 시작일자 and 종료일자
and 종목코드 = nvl (:종목코드, 종목묘드)
and 투자자유형묘드 = nvl(:투자자유형코드, 투자자유형코드)
and 주문매체구분코드 = nvl(:주문매체구분코드, 주문매체구분묘드)
단 한 개의 실행계획을 공유하면서 반복 재사용하게 되므로 라이브러리 캐시 효율 측면에서는 최상의 선택, 인덱스를 비효율적으로 사용
1. 거 래 일자 between
2. 거래일자 between, 종목코드 =
3. 거래일자 between, 종목코드 투자자유형코드 =
4. 거래일자 between, 종목코드 투자자유형코드 주문매체구분코드 =
5. 거래일자 between, 종목코드 주문매체구분코드 =
6. 거래일자 between, 투자자유형코드 =
7. 거래일자 between, 투자자유형코드 주문매체구분코드 =
8, 거래일자 between, 주문매체구분묘드 =
<인덱스 구성>
index 1 : 종목코드+거래일자
index 2 : 투자자유형코드+거래일자+주문매체구분코드
index 3 : 거래일자+주문매체구분코드
select 거래일자, 투자자유형코드, 회원번호
, 체결건수, 체결수량, 거래대금
from 일별종목거래
where :종목코드 is not null
and 거래일자 between :시작 and :종료
and 종목코드=:종목코드
and 투자자유형코드=nvl(:투자자유형, 투자자유형코드)
and 주문매체구분코드=nvl(:주문매체, 주문매체구분코드)
union all
select 거래일자, 투자자유형코드, 회원번호
, 체결건수, 체결수량, 거래대금
from 일별종목거래
where :종목코드 is null and :투자자유형 is not null
and 거래일자 between :시작 and :종료
and 투자자유형코드=nvl(:투자자유형, 투자자유형코드)
and 주문매체구분코드=nvl(:주문매체, 주문매체구분코드)
union all
select 거래일자, 투자자유형코드, 회원번호
, 체결건수, 체결수량, 거래대금
from 일별종목거래
where :종목코드 is null and :투자자유형 is null
and 거래일자 between :시작 and :종료
and 주문매체구분코드=nvl(:주문매체, 주문매체구분코드)
SQLStmt := 'SELECT 거래일자, 종목코드 투자자유형코드, '
|| '주문매체코드, 체결건수, 체결수량, 거래대금 '
|| FROM 일별종목거래 '
||WHERE 거래 일자 BETWEEN :1 AND :2'
If종목코드 IS NULL Then
SQLStrnt : = SQLStrnt || 'AND : 3 IS NULL';
Else
SQLStrnt : = SQLStrnt || 'AND 종목코드 :3';
End If;
If 투자자유형 IS NULL Then
SQLStrnt : = SQLStrnt || 'AND : 4 IS NULL';
Else
SQLStrnt : = SQLStrnt || 'AND 투자자유형코드 :4' ;
End If;
EXECUTE IMMEDIATE SQLStrnt
INIO :A, :B, :C, :D, :E, : F, :G
USING :시작일자, :종료일자, :종목코드, :투자자유형코드;
select * from 일별종목거래
where (:isu_cd is null or isu_cd :isu_cd)
Execution Plan
-------------------------------------------------------------
o SELECT STATEMENT Optirnizer=ALL rows
1 0 TABLE ACCES (FULL) OF '일별종목거래' (TABLE)
항상 Table Full Scan으로 처 리되므로 인텍스 활용이 필요할 때는 이 방식을 사용해선 안된다.
select * frαn 일별종목거 래
where isu_cd like :isu_cd || '%'
Execution Plan
-------------------------------------------------------------
o SELECT STATEMENT Optirnizer=ALL rows
1 0 TABLE ACCESS (BY LOCAL INDEX ROWWID) OF ' 일별종목거래' (TABLE)
2 1 INDEX (RANGE SCAN) OF '일별종목거래 PK' (INDEX (UNIQUE))
인텍스 사용이 가능하지만 시용자가 :isu_cd 값을 입력하지 않았을 때 Tab1e Full Scan이 유리한데도 인텍 스를 사용하게 되므로 성능이 나빠질 수 있다.
select * from 일별종목거래
where isu_cd = nvl (:isu_cd,isu_cd)
Execution Plan
-------------------------------------------------------------
o SELECT STATEMENT Optirnizer=ALL rows
1 0 CONCATENATION
2 1 FILTER
3 2 TABLE ACCESS (FULL) OF '일별종목거래' (TABLE)
4 1 FILTER
5 4 TABLE ACCESS (BY IDCAL 1NDEX ROWID) OF ' 일별종목거 래 ' (TABLE)
6 5 INDEX (RANGE SCAN) OF '일별종목거래 PK' (INDEX (UNIQUE))
select * from 일별종목거래
where isu_cd =decode (:isu_cd, null, isu_cd, :isu_cd)
Execut ion Plan
-------------------------------------------------------------
o SELECT STATEMENT Optirnizer=ALL ROWS
1 0 CONCATENATION
2 1 FILTER
3 2 TABLE ACCESS (EULL) OF '일별종목거래 ' (TABLE)
4 1 FILTER
5 4 TABLE ACCESS (BY IDCAL INDEX ROWID) OF ' 일 별종목거 래 ' (TABLE)
6 5 INDEX (RANGE SCAN) OF '일별종목거래_PK' (INDEX (UNIQUE))
:isu_cd 입력 여부에 따라 Full Table Scan과 lndex Scan으로 실행계획이 자동 분기된다.
단 nvl 또는 decode 함수를사용할 때는해당 컬 럼이 not null 컬럼이어야 하며, null 허용 컬럼일 때는 결과집합이 달라지므로 주의해야 한다.
select * frαn 일별종목거래
where : isu_cd is null
union all
select * from 일별종목거래
where :isu_cd is not null
and isu_cd = :isu_cd
Execution Plan
-------------------------------------------------------------
o SELECT STATEMENT Optimizer=ALL ROWS
1 0 UNICN-ALL
2 1 FILTER
3 2 TABLE ACCESS (FULL) OF '일별종목거래' (TABLE)
4 1 FILTER
5 4 TABLE ACCESS (BY lDCAL INDEX ROWID) OF ' 일별종목거 래 ' (TABLE)
6 5 INDEX (RANGE SCAN) OF '일별종목거래 PK' (INDEX (UNIQUE))
5가지 방식에 대한 선택 기준
1. not null 컬럼 일 때는 nvl, decode를 사용하는것이 좋다편하다(C,D)
2. null 값을 허용하고 인텍스 액세스 조건으로 의미있는 컬럼이라면 union all을 시용해 명시적으로 분기해야 한다.(E)
3. 인덱스 엑세스 조건으로 참여 하지 않는 경우, 즉 인덱스 필터 또는 테이블 필터 조건으로만 사용 되는 컬럼이라면 A와 B 방식중 어떤 방식을 사용 해도 무방하다.(AB)