콘텐츠로 이동

2. Altibase SQL 기본#

이 장에서는 Altibase의 SQL을 사용하기 위한 기본적인 사항들을 설명한다.

주석#

Altibase에서는 SQL문의 임의의 위치에 다음 두 가지 형식의 주석을 사용할 수 있다.

  • /* */
    C언어의 주석 형식과 동일한 방식으로 주석의 시작에 '/*'를 명시하고 주석의 끝에 '*/'를 명시한다. 여러 줄의 주석을 쓸 때 사용한다.
  • --
    한 줄의 주석을 쓸 때 '-'를 연이어 두 번 명시하여 사용한다.

Altibase 객체 (Object)#

Altibase에서 제공하는 데이터베이스 객체(object)는 스키마가 객체와 비스키마 객체로 구분되며, 그 종류는 다음과 같다.

스키마 객체#

  • 제약조건 (constraint)
  • 인덱스 (index)
  • 시퀀스 (sequence)
  • 시노님 (synonym)
  • 테이블 (table)
  • 저장 프로시저 (stored procedure)
  • 뷰 (view)
  • 트리거 (trigger)
  • 데이터베이스 링크(database link)

비 스키마 객체#

  • 사용자 (user)
  • 이중화 (replication)
  • 테이블스페이스 (tablespace)
  • 디렉토리 (directory)

객체 이름 규칙#

객체 이름#

데이터베이스 객체 이름에는 다음의 규칙이 적용된다.

  • 객체의 이름의 최대 길이는 40바이트이다.

  • SQL문에서 객체의 이름을 쓸 때 인용부호는 사용해도 되고 사용하지 않아도 된다. 인용부호로 큰따옴표(")를 사용한다. 객체 생성시 따옴표로 묶어서 이름을 지정하면, 이 후에 그 객체를 참조할 때는 항상 큰따옴표로 묶은 이름을 사용해야 한다.

  • 인용부호가 없는 이름은 대소문자가 구별되지 않는다. Altibase는 내부적으로 인용부호가 없는 이름을 대문자로 변경하며, 인용부호로 묶은 이름은 대소문자가 구별된다. 아래의 이름은 Altibase 내에서 같은 이름으로 사용되기 때문에 같은 이름 공간(Name Space)에서 다른 객체로 사용될 수 없다.

    employees, EMPLOYEES, "EMPLOYEES"
    
  • 인용부호가 없는 이름은 아래의 문자를 포함할 수 있다.

    A-Z, a-z, 0-9, _, $, #
    
  • 객체 이름의 첫 글자는 문자이거나 _ 이어야 한다. 그러나 아래의 문자로는 시작할 수 없다.

    V$, X$ D$
    
  • 인용부호가 있는 이름은 문자, 구두점 또는 공백을 포함할 수 있다. 그러나 큰따옴표(")를 포함할 수 없다.

  • Altibase의 예약어는 객체 이름으로 사용될 수 없다. (Altibase의 예약어 목록은 아래에 나열해 두었다.)

  • 같은 이름공간(Name Space)내에는 같은 이름의 객체가 존재할 수 없다.

    • 다음의 스키마 객체들은 한 이름공간을 공유한다:
      • 테이블
      • 시퀀스
      • 시노님
      • 저장 프로시저
    • 다음의 스키마 객체들은 자신의 이름공간을 따로 소유한다:
      • 제약조건
      • 인덱스
      • 트리거
      • 데이터베이스 링크 객체
    • 테이블과 뷰는 동일한 이름 공간를 공유하므로 동일한 스키마 내에 같은 이름의 테이블과 뷰는 존재할 수 없다. 그러나 테이블과 인덱스는 서로 다른 이름공간에 존재하기 때문에 동일한 스키마 내에 같은 이름의 테이블과 인덱스가 존재할 수 있다.
    • 사용자, 이중화 객체, 테이블스페이스, 디렉터리 객체 같은 비스키마 객체들은 자신의 이름공간을 소유한다.

Altibase가 제공하는 객체에 대한 자세한 설명은 Administrator's Manual을 참고하기 바란다.

비밀번호#

사용자가 Altibase에 접속하기 위해 사용하는 비밀번호 역시 객체 이름과 유사한 제약조건을 가진다. 암호에 사용가능한 문자는 A-Z, a-z, 0-9, _, $ 이다. 또한 Altibase의 예약어는 비밀번호에 사용될 수 없다. 첫 글자는 반드시 문자 또는 _여야 한다. 비밀번호의 최대 길이는 40바이트이다.

Altibase는 기본적으로 사용자 암호를 대소문자 구분 없이 대문자로 인식하여 다룬다. 사용자 암호의 대소문자를 구분하기 위해서는 CASE_SENSITIVE_PASSWORD 프로퍼티를 1로 설정한 다음, CREATE USER 구문으로 사용자를 생성할 때 암호를 큰따옴표(")로 묶는다. 만약 큰따옴표를 쓰지 않고, 암호를 지정하면 CASE_SENSITIVE_PASSWORD 프로퍼티가 1이더라도, 데이터베이스에서 암호를 대문자로 인식한다.

예약어#

다음 단어들은 Altibase에 예약되어 있는 단어들로 데이터베이스 객체 이름이나 비밀번호로 사용할 수 없다. 키워드 오른쪽의 (O)는 해당 키워드가 객체 이름으로는 사용될 수 없지만 테이블의 칼럼 이름으로는 허용됨을 표시한다. 데이터베이스 객체 생성시 또는 SQL구문 작성시에 이를 유념해야 한다. V$RESERVED_WORDS 성능뷰로 예약어를 확인할 수 있다.

_PROWID

FIFO(O)

PRIMARY

ACCESS(O)

FIXED(O)

PRIOR

ADD

FLASHBACK(O)

PROCEDURE

AFTER(O)

FLUSH(O)

PURGE

AGER(O)

FLUSHER(O)

QUEUE

ALL

FOLLOWING(O)

RAISE

ALTER

FOR

READ

AND

FOREIGN

REBUILD

ANY

FROM

RECOVER

APPLY

FULL(O)

REMOVE

ARCHIVE(O)

FUNCTION(O)

RENAME

ARCHIVELOG(O)

GOTO(O)

REPLACE

AS

GRANT

RETURN

ASC

GROUP

RETURNING

AT(O)

HAVING

REVOKE

AUDIT(O)

IF(O)

RIGHT

AUTOEXTEND(O)

IN

ROLLBACK

BACKUP(O)

INDEX

ROLLUP

BEFORE(O)

INITRANS(O)

ROW

BEGIN(O)

INNER(O)

ROWCOUNT

BETWEEN

INSERT

ROWNUM

BODY(O)

INSTEAD

ROWTYPE

BULK

INTERSECT

SAVEPOINT

BY

INTO

SEGMENT

CASCADE(O)

IS

SELECT

CASE

ISOLATION(O)

SEQUENCE

CAST(O)

JOIN(O)

SESSION

CHECKPOINT(O)

KEY(O)

SET

CLOSE(O)

LANGUAGE(O)

SHARD

COALESCE(O)

LATERAL

SOME

COLUMN

LEFT(O)

SPLIT

COMMENT(O)

LESS(O)

SQLCODE

COMMIT(O)

LEVEL

SQLERRM

COMPILE(O)

LIBRARY(O)

START

COMPRESS

LIFO(O)

STEP

COMPRESSED(O)

LIKE

STORAGE

CONJOIN(O)

LIMIT(O)

STORE

CONNECT

LINK

SYNONYM

CONSTANT

LINKER

TABLE

CONSTRAINTS(O)

LOB

THAN

CONTINUE(O)

LOCAL

THEN

CREATE

LOCK

TIMESTAMPADD

CROSS

LOGANCHOR

TO

CUBE(O)

LOGGING

TOP

CURSOR(O)

LOOP

TRIGGER

CYCLE(O)

MAXROWS

TRUE

DATABASE(O)

MAXTRANS

TRUNCATE

DECLARE(O)

MERGE

TYPE

DECRYPT(O)

MINUS

TYPESET

DEFAULT

MODE

UNION

DELAUDIT(O)

MODIFY

UNIQUE

DELETE

MOVE

UNLOCK

DEQUEUE(O)

MOVEMENT

UNPIVOT

DESC

NEW

UNTIL

DETERMINISTIC(O)

NOAUDIT

UPDATE

DIRECTORY(O)

NOCOPY

USING

DISABLE(O)

NOCYCLE

VALUES

DISASTER(O)

NOLOGGING

VARIABLE

DISCONNECT(O)

NOT

VC2COLL

DISJOIN(O)

NULL

VIEW

DISTINCT

NULLS

VOLATILE

DROP

OF

WAIT

EACH(O)

OFF

WHEN

ELSE

OFFLINE

WHENEVER

ELSEIF(O)

OLD

WHERE

ELSIF(O)

ON

WHILE

ENABLE(O)

ONLINE

WITH

END(O)

OPEN

WITHIN

ENQUEUE(O)

OR

WORK

ESCAPE(O)

ORDER

WRAPPED

EXCEPTION

OTHERS

WRITE

EXEC(O)

OUT

 

EXECUTE(O)

OUTER

 

EXISTS

OVER

 

EXIT(O)

PACKAGE

 

EXTENT(O)

PARALLEL

 

EXTENTSIZE(O)

PARTITION

 

FALSE

PIVOT

 

FETCH(O)

PRECEDING

 

[표 2-1] 예약어 목록

힌트 구문#

구문#

hints ::=

hint

전제 조건#

힌트는 아래의 구문에 명시할 수 있다

  • 단순 SELECT, UPDATE, DELETE, INSERT 구문
  • 복잡한 구문에서 메인 쿼리 또는 서브쿼리
  • 복합 구문(집합 연산자로 묶인)에서 첫 번째 쿼리

설명#

SELECT, UPDATE, DELETE, INSERT 키워드 다음에 힌트를 명시할 수 있다.

주석 구분자(/*) 다음의 플러스 기호(+)는 그 주석이 힌트임을 Altibase에 알려주는 역할을 한다. 플러스 기호(+)는 주석 구분자 바로 뒤에 공백 없이 위치해야 한다.

하나의 주석 내에 공백으로 분리하여 여러 힌트를 명시할 수 있다.

힌트에 문법 오류가 있어도 힌트는 무시되고 쿼리는 실행된다.

각각의 힌트에 대한 문법은 다음 절 힌트 목록을 참조한다.

SQL 튜닝을 위한 힌트 선택은 Performance Tuning Guide를 참조한다.

예제#

Direct-Path INSERT Hint#

<질의> T1테이블의 모든 데이터를 Direct-Path INSERT 방식으로 T2테이블에 입력한다.

INSERT /*+ APPEND */ INTO T2 SELECT * FROM T1;

Table Access Method Hints (full scan, index scan, index ascending order scan, index descending order scan, no index scan)#

다음은 사원들 중 모든 여사원의 번호, 이름, 직업을 검색하는 질의이다.

SELECT eno, e_firstname, e_lastname, emp_job FROM employees WHERE sex = 'F';

예를 들어 많은 수의 사원들이 있는 사원 테이블의 성별(SEX) 칼럼에 인덱스가 정의되어 있고, 이 칼럼의 값은 'M' 또는 'F'이다.

만약, 남자 직원과 여자 직원의 비율이 같다면 full scan으로 전체 테이블을 검색하는 것이 index scan으로 검색하는 것보다 더 빠를 것이다. 그러나, 만약 여자 직원의 비율이 남자 직원보다 상대적으로 적다면, index scan이 전체 테이블의 full scan 보다 빠를 것이다. 즉, 칼럼이 서로 다른 두 개의 값만을 가지고 있을 때, 쿼리 옵티마이저는 각 값의 행들이 50%씩 존재한다고 가정해서 비용 기반 접근 방식으로서 index scan 보다 전체 테이블의 full scan을 선택한다.

아래의 질의들에서 access 회수를 비교해 보면 각각 20과 4인 것을 알수 있다.

<질의> 성별이 여자인 직원의 사원 번호, 이름, 직업을 출력하라. (full scan 이용)

iSQL> SELECT /*+ FULL SCAN(employees) */ eno, e_firstname, e_lastname, emp_job
 FROM employees 
 WHERE sex = 'F';
ENO E_FIRSTNAME E_LASTNAME EMP_JOB 
------------------------------------------------
.
.
.
------------------------------------------------
PROJECT ( COLUMN_COUNT: 4, TUPLE_SIZE: 65, COST: 0.18 )
 SCAN ( TABLE: EMPLOYEES, FULL SCAN, ACCESS: 20, COST: 0.14 )
------------------------------------------------

<질의> 성별이 여자인 직원의 사원 번호, 이름, 직업을 출력하라. (index 이용)

iSQL> CREATE INDEX gender_index ON employees(sex);
Create success.
iSQL> SELECT /*+ INDEX(employees, gender_INDEX) use gender_index because there are few female employees */ eno, e_firstname, e_lastname, emp_job
 FROM employees
 WHERE sex = 'F';
ENO E_FIRSTNAME E_LASTNAME EMP_JOB 
------------------------------------------------
.
.
.
------------------------------------------------
PROJECT ( COLUMN_COUNT: 4, TUPLE_SIZE: 65 )
 SCAN ( TABLE: EMPLOYEES, INDEX: GENDER_INDEX, ACCESS: 4, SELF_ID: 2 )
------------------------------------------------

<질의> 1사분기(1월에서 3월까지) 동안의 모든 주문에 대한 주문번호, 상품번호, 주문량을 출력하라 (index 이용). 각 월에 해당하는 주문 테이블의 이름이 orders_## 라고 가정한다.

create view orders as
select ono, order_date, eno, cno, gno, qty from orders_01
union all
select ono, order_date, eno, cno, gno, qty from orders_02
union all
select ono, order_date, eno, cno, gno, qty from orders_03;
create index order1_gno on orders_01(gno);
create index order2_gno on orders_02(gno);
create index order3_gno on orders_03(gno);

iSQL> select /*+ index( orders, 
           orders1_gno, orders2_gno,orders3_gno ) */
           ONO, GNO, QTY
      from orders;
ONO                  GNO         QTY         
-------------------------------------------------
.
.
.
------------------------------------------------
PROJECT ( COLUMN_COUNT: 3, TUPLE_SIZE: 24 )
 VIEW ( ORDERS, ACCESS: 14, SELF_ID: 6 )
  PROJECT ( COLUMN_COUNT: 6, TUPLE_SIZE: 48 )
   VIEW ( ACCESS: 14, SELF_ID: 5 )
    BAG-UNION
     PROJECT ( COLUMN_COUNT: 6, TUPLE_SIZE: 48 )
      SCAN ( TABLE: ORDERS_01, INDEX: ORDERS1_GNO, ACCESS: , SELF_ID: 0 )
     PROJECT ( COLUMN_COUNT: 6, TUPLE_SIZE: 48 )
      SCAN ( TABLE: ORDERS_02, INDEX: ORDERS2_GNO, ACCESS: 4, SELF_ID: 1 )
     PROJECT ( COLUMN_COUNT: 6, TUPLE_SIZE: 48 )
      SCAN ( TABLE: ORDERS_03, INDEX: ORDERS3_GNO, ACCESS: 7, SELF_ID: 4 )
------------------------------------------------

Join Order Hints (ordered, optimized)#

<질의> 주문된 상품을 담당하고 있는 직원의 사원번호, 이름과 해당 고객의 이름을 출력하라. (employees 테이블과 customers 테이블을 조인하고, 그 결과를 orders 테이블과 조인하기 위해 ORDERED 힌트를 사용하라.)

iSQL> SELECT /*+ ORDERED */ DISTINCT o.eno, e.e_lastname, c.c_lastname
FROM employees e, customers c, orders o
WHERE e.eno = o.eno AND o.cno = c.cno;
ENO E_LASTNAME C_LASTNAME 
------------------------------------------------
.
.
.
------------------------------------------------
PROJECT ( COLUMN_COUNT: 3, TUPLE_SIZE: 48 )
 DISTINCT ( ITEM_SIZE: 40, ITEM_COUNT: 21, BUCKET_COUNT: 1024, ACCESS: 21, SELF_ID: 4, REF_ID: 3 )
 JOIN
 JOIN
 SCAN ( TABLE: EMPLOYEES E, FULL SCAN, ACCESS: 20, SELF_ID: 1 )
 SCAN ( TABLE: CUSTOMERS C, FULL SCAN, ACCESS: 400, SELF_ID: 2 )
 SCAN ( TABLE: ORDERS O, FULL SCAN, ACCESS: 12000, SELF_ID: 3 )
------------------------------------------------

<질의> 주문된 상품을 담당하고 있는 직원의 사원번호, 이름과 해당 고객의 이름을 출력하라. (FROM 절의 테이블들의 순서에 상관없이 옵티마이저에 의해서 테이블 조인 순서가 결정되도록 하라.)

iSQL> SELECT DISTINCT o.eno, e.e_lastname, c.c_lastname
FROM employees e, customers c, orders o 
WHERE e.eno = o.eno AND o.cno = c.cno;
ENO E_LASTNAME C_LASTNAME 
------------------------------------------------
.
.
.
------------------------------------------------
PROJECT ( COLUMN_COUNT: 3, TUPLE_SIZE: 48 )
 DISTINCT ( ITEM_SIZE: 40, ITEM_COUNT: 21, BUCKET_COUNT: 1024, ACCESS: 21, SELF_ID: 4, REF_ID: 1 )
 JOIN
 JOIN
 SCAN ( TABLE: CUSTOMERS C, FULL SCAN, ACCESS: 20, SELF_ID: 2 )
 SCAN ( TABLE: ORDERS O, INDEX: ODR_IDX2, ACCESS: 30, SELF_ID: 3 )
 SCAN ( TABLE: EMPLOYEES E, INDEX: __SYS_IDX_ID_366, ACCESS: 30, SELF_ID: 1 )
------------------------------------------------

Optimizer Mode Hints (rule, cost)#

iSQL> SELECT /*+ RULE */ * FROM t1, t2 WHERE t1.i1 = t2.i1;
iSQL> SELECT /*+ COST */ * FROM t1, t2 WHERE t1.i1 = t2.i1;

Normal Form Hints (cnf, dnf)#

iSQL> SELECT /*+ CNF */ * FROM t1 WHERE i1 = 1 OR i1 = 2;
iSQL> SELECT /*+ DNF */ * FROM t1 WHERE i1 = 1 OR i1 = 2;

Join Method Hints (nested loop, hash, sort, sort merge)#

iSQL> SELECT /*+ USE_NL (t1,t2) */ * FROM t1, t2 WHERE t1.i1 = t2.i1;
iSQL> SELECT /*+ USE_HASH (t1,t2) */ * FROM t1, t2 WHERE t1.i1 = t2.i1;
iSQL> SELECT /*+ USE_SORT (t1,t2) */ * FROM t1, t2 WHERE t1.i1 = t2.i1;
iSQL> SELECT /*+ USE_MERGE (t1,t2) */ * FROM t1, t2 WHERE t1.i1 = t2.i1;

Hash Bucket Size Hints (hash bucket count, group bucket count, set bucket count)#

iSQL> SELECT /*+ HASH BUCKET COUNT (20) */ DISTINCT * FROM t1;
iSQL> SELECT * FROM t1 GROUP BY i1, i2;
iSQL> SELECT /*+ GROUP BUCKET COUNT (20) */ * FROM t1 GROUP BY i1, i2;
iSQL> SELECT * FROM t1 INTERSECT SELECT * FROM t2;
iSQL> SELECT /*+ SET BUCKET COUNT (20) */  * FROM t1 INTERSECT SELECT * FROM t2;

Push Predicate Hints#

<질의> 1사분기(1월에서 3월까지) 동안 발생한 주문 중에서 한번의 주문수량이 10000개이상인 고객의 명단과 상품번호을 구하라.(고객 테이블과 주문 테이블을 조인하기 위해 Push Predicate 힌트를 사용하라.)

iSQL> create view orders_t as
    2 select ono, order_date, eno, cno, gno, qty from orders orders_01
    3 union all
    4 select ono, order_date, eno, cno, gno, qty from orders orders_02
    5 union all
    6 select ono, order_date, eno, cno, gno, qty from orders orders_03;
Create success.
iSQL> alter session set explain plan = only;
Alter success.
iSQL> alter session set trclog_detail_predicate =1;
Alter success.
iSQL> select /*+ PUSH_PRED(orders_t) */ c_lastname, gno
    2 from customers, orders_t
    3 where customers.cno = orders_t.cno
    4 and orders_t.qty >= 10000;
C_LASTNAME            GNO
-------------------------------------
.
.
.
-----------------------------------------------------------
PROJECT ( COLUMN_COUNT: 2, TUPLE_SIZE: 34, COST: 1.68 )
 JOIN ( METHOD: NL, COST: 1.67 )
  SCAN ( TABLE: SYS.CUSTOMERS, FULL SCAN, ACCESS: ??, COST: 0.23 )
  VIEW ( SYS.ORDERS_T, ACCESS: ??, COST: 0.07 )
   PROJECT ( COLUMN_COUNT: 6, TUPLE_SIZE: 48, COST: 0.04 )
    VIEW ( ACCESS: ??, COST: 0.04 )
     BAG-UNION
      PROJECT ( COLUMN_COUNT: 6, TUPLE_SIZE: 48, COST: 0.01 )
       SCAN ( TABLE: SYS.ORDERS ORDERS_01, INDEX: SYS.ODR_IDX2, RANGE SCAN, ACCESS: ??, COST: 0.01 )
        [ VARIABLE KEY ]
        OR
         AND
          CUSTOMERS.CNO = ORDERS_01.CNO
        [ FILTER ]
        ORDERS_01.QTY >= 10000
      PROJECT ( COLUMN_COUNT: 6, TUPLE_SIZE: 48, COST: 0.01 )
       SCAN ( TABLE: SYS.ORDERS ORDERS_02, INDEX: SYS.ODR_IDX2, RANGE SCAN, ACCESS: ??, COST: 0.01 )
        [ VARIABLE KEY ]
        OR
         AND
          CUSTOMERS.CNO = ORDERS_02.CNO
        [ FILTER ]
        ORDERS_02.QTY >= 10000
      PROJECT ( COLUMN_COUNT: 6, TUPLE_SIZE: 48, COST: 0.01 )
       SCAN ( TABLE: SYS.ORDERS ORDERS_03, INDEX: SYS.ODR_IDX2, RANGE SCAN, ACCESS: ??, COST: 0.01 )
        [ VARIABLE KEY ]
        OR
         AND
          CUSTOMERS.CNO = ORDERS_03.CNO
        [ FILTER ]
        ORDERS_03.QTY >= 10000
-----------------------------------------------------------

힌트 목록#

이 절은 힌트 사용법과 의미를 간략히 설명한다. 각 힌트가 쿼리 옵티마이저를 위해 처리하는 방식에 대한 설명은 Performance Tuning Guide의 3장 쿼리 옵티마이저를 참고한다.

힌트는 그 기능에 따라 아래와 같이 분류된다.

분류 기준 힌트
최적화 접근법과 목표 COST RULE FIRST_ROWS
정규화 형태 CNF DNF NO_EXPAND USE_CONCAT
액세스 방법 FULL SCAN INDEX INDEX ASC INDEX_ASC INDEX DESC
INDEX_DESC NO INDEX NO_INDEX
병렬 처리 PARALLEL NO_PARALLEL
조인 순서 LEADING ORDERED
조인 방법 USE_NL USE_FULL_NL USE_FULL_STORE_NL USE_INDEX_NL
USE_ANTI USE_HASH USE_ONE_PASS_HASH USE_TWO_PASS_HASH
USE_INVERSE_HASH USE_SORT USE_ONE_PASS_SORT
USE_TWO_PASS_SORT USE_MERGE
NO_USE_NL NO_USE_HASH NO_USE_MERGE NO_USE_SORT
중첩된 부질의 중첩 풀기 시 조인 방법 NL_SJ HASH_SJ SORT_SJ MERGE_SJ NL_AJ HASH_AJ SORT_AJ MERGE_AJ INVERSE_JOIN NO_INVERSE_JOIN
쿼리 변환 NO_MERGE NO_TRANSITIVE_PRED NO_UNNEST UNNEST
중간 결과 저장 매체 TEMP_TBS_DISK TEMP_TBS_MEMORY
해시 버킷 크기 GROUP BUCKET COUNT HASH BUCKET COUNT SET BUCKET COUNT
그룹 처리 방법 GROUP_HASH GROUP_SORT
중복 제거 처리 방법 DISTINCT_HASH DISTINCT_SORT
뷰 최적화 방법 NO_PUSH_SELECT_VIEW PUSH_SELECT_VIEW PUSH_PRED
단순 쿼리 EXEC_FAST NO_EXEC_FAST
단순 필터 SERIAL_FILTER NO_SERIAL_FILTER
그 외 APPEND DELAY NO_DELAY HIGH_PRECISION KEEP_PLAN
NO_PLAN_CACHE RESULT_CACHE TOP_RESULT_CACHE
PLAN_CACHE_KEEP

Altibase는 모든 힌트에 대해 운영 프로그램을 수정하지 않고 ALTIBASE 에만 적용되는 힌트를 제공한다. 기존 힌트에 'ALTI_' 접두사를 붙여 사용하며 두 개 이상의 키워드로 구성된 힌트일 경우 space 를 under bar 로 대체한 후 'ALTI_' 접두사를 붙여 사용한다.

APPEND#

Direct-Path INSERT가 수행되도록 지시하는 힌트이다. 이 힌트는 INSERT 구문에만 사용할 수 있다. Direct-Path INSERT는 데이터가 입력될 때 페이지의 빈 공간을 찾아 들어가는 대신 새로운 페이지를 만들어 데이터를 입력하는 방식이다. Direct-Path INSERT와 관련된 통계 정보는 V$DIRECT_PATH_INSERT 성능 뷰를 조회해서 확인할 수 있다.

append

CNF#

WHERE절의 조건문들을 Conjunctive Normal Form으로 정규화할 것을 지시하는 힌트이다.

cnf

COST#

비용 기반으로 최적화된 실행 계획을 생성하도록 지시하는 힌트이다.

cost

DELAY#

쿼리의 프로퍼티와 상관없이 실행 계획의 그래프를 기준으로 hierarchy, sorting, windowing, grouping, set, distinction의 실행(execute)이 패치(fetch)에서 수행되도록 하는 지연 기능을 활성화한다.

DISTINCT_HASH#

해싱 방식으로 DISTINCT를 처리할 것을 지시하는 힌트이다.

distinct_hash

DISTINCT_SORT#

정렬 방식으로 DISTINCT를 처리할 것을 지시하는 힌트이다.

distinct_sort

DNF#

WHERE절의 조건문들을 Disjunctive Normal Form으로 정규화할 것을 지시하는 힌트이다.

dnf

EXEC_FAST#

EXECUTOR_FAST_SIMPLE_QUERY 프로퍼티가 비활성화된 상태에서 힌트가 명시되면, 단순한 SELECT, INSERT, UPDATE, DELETE 구문은 SIMPLE QUERY로 동작한다. SIMPLE QUERY가 적용된 경우 실행 계획에 출력된다.

FIRST_ROWS#

처음 n개의 행을 가장 효율적으로 반환할 수 있는 실행 계획을 생성하도록 지시하는 힌트이다.

first_rows

FULL SCAN#

명시한 테이블에 대해 테이블 전체 스캔을 수행할 것을 지시하는 힌트이다.

full scan

GROUP BUCKET COUNT#

GROUP-AGGREGATION과 AGGREGATION 실행 노드의 해시 버킷 수를 지정하는 힌트이다.

group bucket count

GROUP_HASH#

해싱 방식으로 GROUP BY절을 처리할 것을 지시하는 힌트이다.

group_hash

GROUP_SORT#

정렬 방식으로 GROUP BY절을 처리할 것을 지시하는 힌트이다.

group_sort

HASH_AJ#

중첩된 부질의가 Hash Join을 사용하여 Anti Join 하도록 지시하는 힌트이다. 해당 힌트는 부질의 내부에 정의해야 효과가 있으며, 만약 부질의가 Semi Join으로 풀리거나, 풀 수 없는 경우에는 효과가 없다.

hash_aj

HASH BUCKET COUNT#

HASH와 DISTINCT 실행 노드의 해시 버킷 수를 지정하는 힌트이다.

hash bucket count

HASH_SJ#

중첩된 부질의가 Hash Join을 사용하여 Semi Join 하도록 지시하는 힌트이다. 해당 힌트는 부질의 내부에 정의해야 효과가 있다. 만약 부질의가 Anti Join으로 풀리거나 풀리지 않는 경우에는 효과가 없다.

hash_sj

HIGH_PRECISION#

사칙 연산 및 mod 연산 시 오차 발생을 방지하기 위하여 사용하는 힌트이다.

이 힌트를 사용할 때 데이타 타입으로 float 타입을 사용하여 연산한다. float 타입으로 연산할 경우 real이나 double 데이터 타입보다 연산 성능이 떨어질 수 있지만, 38자리까지의 사칙 연산 및 mod 연산의 정밀도를 보장한다.

INDEX#

명시된 인덱스를 사용하여 해당 테이블에 대해서 인덱스 스캔을 수행하도록 지시하는 힌트이다.

index

INDEX ASC#

명시된 인덱스를 사용하여 해당 테이블에 대해서 인덱스 스캔을 수행하되, 오름 차순으로 탐색한다.

index_asc

INDEX_ASC#

INDEX ASC힌트와 같은 동작을 한다.

INDEX DESC#

명시된 인덱스를 사용하여 해당 테이블에 대해서 인덱스 스캔을 수행하되, 내림 차순으로 탐색한다.

index desc

INDEX_DESC#

INDEX DESC와 같은 동작을 한다

INVERSE_JOIN#

중첩된 부질의가 Semi Join 또는 Anti Join을 하는 경우 Inverse Join1을 반드시 사용하도록 지시하는 힌트이며, 부질의 내에 명시해야 한다.

해당 힌트는 Semi Join 또는 Anti Join 방법을 지시하는 다른 힌트와 함께 사용할 수 있다. 예를 들어 HASH_SJ와 함께 사용하는 경우, Hash Join이면서 Inverse Join인 Inverse Hash 조인을 사용하도록 지시한다.

inverse_join

KEEP_PLAN#

KEEP_PLAN는 한 번 생성된 플랜이 참조하는 테이블의 통계 정보가 변경되더라도 플랜이 재생성되는 것을 방지하고 그대로 사용하도록 지시하는 힌트이다. KEEP_PLAN 힌트는 쿼리의 direct/execute 수행뿐 아니라 prepare/execute 수행시에도 사용 가능하다.

keep_plan

LEADING#

힌트에 사용된 테이블들을 먼저 조인되도록 한다. 두 개 이상의 LEADING 힌트를 사용한 경우에는 처음 LEADING 힌트만 효과가 있다. ORDERED 힌트와 함께 사용된 경우에는 ORDERED 힌트가 무시된다. 힌트에 사용된 테이블에 Lateral View를 명시한 경우에는 효과가 없다.

MERGE_AJ#

중첩된 부질의가 Merge Join을 사용하여 Anti Join 하도록 지시하는 힌트이다. 해당 힌트는 부질의 내부에 정의해야 효과가 있으며, 만약 부질의가 Semi Join으로 풀리거나, 풀 수 없는 경우에는 효과가 없다.

merge_aj

MERGE_SJ#

중첩된 부질의가 Merge Join을 사용하여 Semi Join 하도록 지시하는 힌트이다. 해당 힌트는 부질의 내부에 정의해야 효과가 있으며, 만약 부질의가 Anti Join으로 풀리거나, 풀 수 없는 경우에는 효과가 없다.

merge_sj

NL_AJ#

중첩된 부질의가 Nested Loop Join을 사용하여 Anti Join 하도록 지시하는 힌트이다. 해당 힌트는 부질의 내부에 정의해야 효과가 있으며, 만약 부질의가 Semi Join으로 풀리거나, 풀 수 없는 경우에는 효과가 없다.

nl_aj

NL_SJ#

중첩된 부질의가 Nested Loop Join을 사용하여 Semi Join 하도록 지시하는 힌트이다. 해당 힌트는 부질의 내부에 정의해야 효과가 있다. 만약 부질의가 Anti Join으로 풀리거나 풀리지 않는 경우에는 효과가 없다.

nl_sj

NO_DELAY#

쿼리의 프로퍼티와 상관없이 실행 계획의 그래프를 기준으로 hierarchy, sorting, windowing, grouping, set, distinction의 실행(execute)이 패치(fetch)에서 수행되도록 하는 지연 기능을 비활성화한다.

NO_EXEC_FAST#

EXECUTOR_FAST_SIMPLE_QUERY 프로퍼티가 활성화된 상태에서 힌트가 명시되면, 단순한 SELECT, INSERT, UPDATE, DELETE 구문이더라도 SIMPLE QUERY로 동작되지 않는다.

NO_EXPAND#

CNF힌트와 같은 동작을 한다.

NO INDEX#

명시된 인덱스를 사용해서 해당 테이블에 대한 인덱스 스캔을 수행하지 않도록 지시하는 힌트이다.

no index

NO_INDEX#

NO INDEX힌트와 같은 동작을 한다.

NO_INVERSE_JOIN#

중첩 부질의가 Semi Join 또는 Anti Join을 하는 경우, Inverse Join이 아닌 One-pass Hash Join이나 Two-pass Hash join을 선택하여 사용하도록 지시하는 힌트이다. 부질의 내에 명시해야 한다.

해당 힌트는 Semi Join 또는 Anti Join 방법을 지시하는 다른 힌트와 함계 사용할 수 있다. 예를 들어 HASH_SJ와 함께 사용하는 경우, Hash Join이면서 One-Pass Hash Join과 Two-Pass Hash Join 중 하나를 사용하도록 지시한다.

no_inverse_join

NO_MERGE#

메인 쿼리와 인라인 뷰 쿼리를 하나의 쿼리로 병합하지 않도록 지시하는 힌트이다.

no_merge

NO_PARALLEL#

NOPARALLEL 힌트와 같은 동작을 한다.

NO_PLAN_CACHE#

NO_PLAN_CACHE는 생성된 플랜을 플랜 캐시에 저장하지 않도록 지시하는 힌트이다.

no_plan_cache

NO_PUSH_SELECT_VIEW#

뷰 외부의 WHERE절의 조건을 뷰 내부로 이동하여 처리하지 않도록 지시하는 힌트이다.

no_push_select_view

NO_SERIAL_FILTER#

SERIAL_EXECUTE_MODE 프로퍼티가 활성화된 상태에서 힌트가 명시되면, Serial Execute Mode 로 동작되지 않는다.

no_serial_filter

NO_TRANSITIVE_PRED#

조건절 이행을 배제하는 힌트이다. 조건절 이행에 대해서는 "Performance Tuning Guide > 3장 쿼리 옵티마이저 > 쿼리 변환 > 조건절 이행"을 참고한다.

no_transitive_pred

NO_UNNEST#

Subquery Unnesting을 하지 말 것을 지시하는 힌트이다.

no_unnest

NO_USE_HASH#

HASH를 제외한 힌트 중에 조인방법이 선택된다.

NO_USE_MERGE#

MERGE를 제외한 힌트 중에 조인방법이 선택된다.

NO_USE_NL#

NL를 제외한 힌트 중에 조인방법이 선택된다.

NO_USE_SORT#

SORT를 제외한 힌트 중에 조인방법이 선택된다

PARALLEL#

일반 테이블 또는 파티션드 테이블을 스캔할 때 병렬 질의를 설정할 수 있는 힌트이다.

  • NOPARALLEL: 병렬로 처리하지 않는다.
  • PARALLEL integer: integer에 명시된 개수만큼의 쓰레드가 병렬로 처리한다.

parallel

PLAN_CACHE_KEEP#

Plan을 victim 선정 과정에서 제외시켜 Plan Cache내에 유지하도록 지시하는 힌트이다. 해당 힌트는 hardprepare 과정에서 적용된다. 그래서 사용자가 해당 plan을 unkeep으로 전환했을 때 softprepare가 발생해도 다시 keep 상태로 전환되지 않는다.

plan_cache_keep

ORDERED#

FROM절에 나열된 순서대로 조인하도록 지시하는 힌트이다.

order

PUSH_PRED#

메인 쿼리의 WHERE 절에서 뷰와 관련된 조인 조건절을 뷰 안으로 밀어넣도록 지시하는 힌트이다.

push_pred

PUSH_SELECT_VIEW#

뷰 외부의 WHERE절의 조건을 뷰 내부로 이동하여 처리하도록 지시하는 힌트이다.

push_select_view

RESULT_CACHE#

중간 결과를 캐시하는 ResultCache를 사용하는 힌트이다.

RULE#

비용을 배제하고 규칙 기반으로 최적화된 실행 계획을 생성하도록 지시하는 힌트이다.

rule

SET BUCKET COUNT#

SET-INTERSECT와 SET-DIFFERENCE 실행 노드의 해시 버킷 수를 지정하는 힌트이다.

set_bucket_count

SERIAL_FILTER#

SERIAL_EXECUTE_MODE 프로퍼티가 비활성화된 상태에서 힌트가 명시되면, Serial Execute Mode 로 동작한다.

serial_filter

SORT_AJ#

중첩된 부질의가 Sort Join을 사용하여 Anti Join 하도록 지시하는 힌트이다. 해당 힌트는 부질의 내부에 정의해야 효과가 있으며, 만약 부질의가 Semi Join으로 풀리거나, 풀 수 없는 경우에는 효과가 없다.

sort_aj

SORT_SJ#

중첩된 부질의가 Sort Join을 사용하여 Semi Join 하도록 지시하는 힌트이다. 해당 힌트는 부질의 내부에 정의해야 효과가 있다. 만약 부질의가 Anti Join으로 풀리거나 풀리지 않는 경우에는 효과가 없다.

sort_sj

TEMP_TBS_DISK#

질의 처리 중에 생성되는 모든 중간 결과를 디스크 임시 공간에 저장하도록 지시하는 힌트이다.

temp_tbs_disk

TEMP_TBS_MEMORY#

질의 처리 중에 생성되는 모든 중간 결과를 메모리 임시 공간에 저장하도록 지시하는 힌트이다.

temp_tbs_memory

TOP_RESULT_CACHE#

최종 결과를 캐시하는 Top Result Cache를 사용하는 힌트이다.

UNNEST#

Subquery Unnesting을 하도록 지시하는 힌트이다.

unnest

USE_ANTI#

Full outer join 쿼리에서 명시된 테이블에 대해 left outer join과 anti outer join을 수행하고 그 결과를 concatenation하도록 지시하는 힌트이다. 단, 조인되는 양쪽 칼럼에 인덱스가 모두 존재하는 경우에만 해당 힌트가 적용된다. ANTI-OUTER-JOIN 노드를 참고한다.

use_anti

USE_CONCAT#

DNF 힌트와 같은 동작을 한다.

USE_FULL_NL#

Full nested loop 조인을 사용해서 명시된 테이블을 조인하도록 지시하는 힌트이다.

use_full_nl

USE_FULL_STORE_NL#

Full store nested loop 조인을 사용해서 명시된 테이블을 조인하도록 지시하는 힌트이다.

use_full_store_nl

USE_HASH#

Hash 조인을 사용해서 명시된 테이블을 조인하도록 지시하는 힌트이다. 단 hasing 술어가 하나도 없을 경우 Nested loop 조인이 사용된다.

use_hash

USE_INDEX_NL#

Index nested loop 조인을 사용해서 명시된 테이블을 조인하도록 지시하는 힌트이다.

use_index_nl

USE_INVERSE_HASH#

inverse hash 조인을 사용해서 명시된 테이블을 조인하도록 지시하는 힌트이다.

use_inverse_hash

USE_MERGE#

Sort Merge 조인을 사용해서 명시된 테이블을 조인하도록 지시하는 힌트이다. 단 sorting 술어가 하나도 없을 경우 Nested loop 조인이 사용된다.

use_merge

USE_NL#

Nested loop 조인을 사용해서 명시된 테이블을 조인하도록 지시하는 힌트이다.

use_nl

USE_ONE_PASS_HASH#

One-pass hash 조인을 사용해서 명시된 테이블을 조인하도록 지시하는 힌트이다.

use_one_pass_hash

USE_ONE_PASS_SORT#

One-pass sort 조인을 사용해서 명시된 테이블을 조인하도록 지시하는 힌트이다.

use_two_pass_sort

USE_SORT#

Sort 조인을 사용해서 명시된 테이블을 조인하도록 지시하는 힌트이다. 단 sorting 술어가 하나도 없을 경우 Nested loop 조인이 사용된다.

use_sort

USE_TWO_PASS_HASH#

Two-pass hash 조인을 사용해서 명시된 테이블을 조인하도록 지시하는 힌트이다.

use_two_pass_hash

USE_TWO_PASS_SORT#

Two-pass sort 조인을 사용해서 명시된 테이블을 조인하도록 지시하는 힌트이다.

use_two_pass_sort


  1. Inverse Join이란 Inverse Index Nested Loop, Inverse Hash, Inverse Sort를 통칭한다. Inverse Join에 대한 자세한 설명은 Performance Tuning Guide를 참조하기 바란다.