쿼리 ========================================= IRIS는 사용자가 IRIS에 저장된 데이터를 자유로이 사용할 수 있도록 표준 SQL 쿼리를 지원합니다. 사용자는 iplus 혹은 API를 이용하여 쿼리를 실행함으로써 원하는 결과를 얻을 수 있습니다. 본 장에서는 iplus 상에서 SELECT, INSERT, UPDATE, DELETE 등 주요 쿼리 문을 작성하는 방법을 설명 합니다. 또한 IRIS에 접속을 할 경우 특정 데이터베이스를 선택하게 되는데, 선택된 데이터베이스가 아닌 다른 데이터베이스에 존재하는 테이블을 사용할 경우에는 다음과 같이 데이터베이스명을 명시적으로 적어 주어야 합니다. .. code:: SELECT * FROM {database_name}.{table_name}; 테이블 생성하기 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ IRIS에서 테이블을 생성하는 방법은 일반적인 데이터베이스에서 쿼리를 이용해서 테이블을 생성하는 방법과 유사합니다. 아래는 일반적인 데이터베이스에서 사용하는 테이블 생성 쿼리의 예입니다. .. code:: CREATE TABLE LOCAL_TEST_TABLE ( Id varchar(20) not null, ddate date, ddata varchar(20), . . . ); IRIS에서 테이블을 생성하기 위해서는, 상기의 쿼리에 몇 가지 옵션들이 추가됩니다. 아래는 IRIS에서 테이블을 생성하는 쿼리문의 예를 보여주고 있습니다. .. code:: CREATE TABLE LOCAL_TEST_TABLE ( id TEXT, ddate TEXT, ddata TEXT ) datascope LOCAL ramexpire 30 diskexpire 34200 partitionkey id partitiondate ddate partitionrange 10 ; 위의 테이블 생성을 위한 쿼리에서 사용되는 옵션에 대한 설명은 다음과 같습니다. **datascope** datascope는 데이터의 저장 방식, 즉 데이터 테이블의 유형을 설정하는 옵션입니다. 사용자는 생성하는 테이블이 GLOBAL 테이블인지 혹은 LOCAL 테이블인지 테이블의 유형을 지정할 수 있습니다. 테이블 유형에 대한 상세한 설명은 “IRIS System Overview”를 참조하시기 바랍니다. **ramexpire** ramexpire는 데이터를 메모리에 보관하는 시간을 설정하는 옵션입니다. IRIS에 데이터가 입력되면, 먼저 메모리에 보관한 후, ramexpire에서 지정된 시간이 경과되면 자동으로 디스크로 옮겨서 저장하게 됩니다. Ramexpire는 분 단위로 설정할 수 있으며, default값은 제공되지 않습니다. Ramexpire를 너무 큰 값으로 설정하면, 오랜 기간 동안 메모리에 데이터를 보관하여야 하며, 결국 메모리의 부족 등으로 인하여 노드에서의 데이터 처리에 문제가 발생할 수 있습니다. 따라서, 메모리의 용량과 데이터 량에 따라 ramexpire 값을 적절하게 설정하여야 합니다. 글로벌 테이블의 경우, 데이터 량이 크지 않으므로 ramexpire를 0으로 설정하여 영구 저장됩니다. **diskexpire** diskexpire는 데이터를 디스크에 보관하는 기간을 설정하는 옵션입니다. Diskexpire는 분 단위로 설정할 수 있으며, 디스크의 용량과 데이터 량에 따라 적절하게 설정하여야 합니다. 글로벌 테이블의 경우, diskexpire를 0으로 설정되어 영구 저장됩니다. 글로벌 테이블은 마스터 노드의 경우, 디스크에 저장되며, 데이터 노드의 경우, 메모리에 저장됩니다. **partitionkey** 데이터가 IRIS에 입력되면, 동일한 partitionkey 값을 가지며, 동일한 기간 동안 발생된 데이터들로 분류하여 저장하게 됩니다. 위의 예시에서는 partitionkey를 id로 지정하였습니다. 즉, 입력되는 데이터를 id 컬럼의 값을 partitionkey로 사용하여 분류한다는 의미입니다. 만일, datascope가 글로벌 테이블인 경우, partitionkey가 불필요하기 때문에 none으로 자동 설정됩니다. **partitiondate** partitiondate는 입력되는 데이터를 동일한 기간에 발생한 데이터들로 분류하기 위하여 사용합니다. 위의 예시에서는 partitiondate를 ddate로 지정하였습니다. 즉, 입력되는 데이터의 ddate 컬럼의 값에 따라 데이터를 분류한다는 의미입니다. Partitiondate로 설정되는 컬럼 값의 형식은 14자리의 숫자(YYYYMMDDHHMMSS)로 이루어져야 합니다. 만일, datascope가 글로벌 테이블인 경우, partitiondate가 불필요하기 때문에 none으로 자동 설정됩니다. **partitionrange** partitionrange는 입력되는 데이터를 상기의 partitiondate로 설정한 컬럼의 값에 따라 동일 그룹으로 분류할때, 해당되는 기간을 결정하는 옵션입니다. 예를 들어, partitionrange를 10으로 설정하였다면, partitiondate 값이 특정 시각을 기준으로 10분동안 발생된 데이터가 동일 그룹으로 분류됩니다. Partitionrange는 분 단위로 설정 가능합니다. 만일, partitionrange를 크게 설정하면, 동일 그룹으로 분류되는 데이터의 수가 커져, IRIS로 로딩하는 성능에 영향을 줄 수 있으므로 적정한 값을 설정하여야 합니다. 만일, datascope가 글로벌 테이블인 경우, partitionrange가 불필요하기 때문에 0으로 자동 설정됩니다. 만일, datascope가 로컬 테이블인 경우, partitionrange의 값은 1 <= partitionrange <= 1440의 범위에서 설정합니다. 테이블 관리하기 ----------------------------------------- IRIS 사용자는 IRIS에서 제공하는 .table 명령어를 이용하여 IRIS 테이블 정보를 조회할 수 있으며, 쿼리를 통해 테이블을 생성, 삭제 할 수 있습니다. 테이블 관리 명령어는 모든 사용자가 실행할 수 있습니다. IRIS 관리자와 일반 사용자 모두 글로벌 테이블과 로컬 테이블을 생성, 수정, 삭제할 수 있습니다. 시스템 테이블의 경우, IRIS 시스템에 대한 정보가 저장된 테이블이며, IRIS 설치 시점에 제공 되며, IRIS 관리자에 의하여 수정할 수 있습니다. 테이블 관리를 위하여 제공되는 명령어는 다음과 같습니다. .. code:: iplus> .table Ret : +OK Success HELP ====================================================================================================================== table command help list : show table list ex) .table list [options] you needs option help, .table list -h info : show detail table info ex) .table info [table name] columns : show detail table columns info ex) .table columns [table name] schema : show tables schema or set tables schema ex) .table schema [table name] --edit {query} expire : set table expire ex) .table expire {table_name} [disk | ram] {exp_time} range : set table range ex) .table range {table_name} {table_range} option : show option list or set table option ex) .table option ex) .table option {table_name} [disk | ram] [LOCAL_TIME_BASE|PARTITION_BASE|KEY_BASE|RECYCLEBIN|OFF] size : show table size ex) .table size index : show table index ex) .table index ====================================================================================================================== 21 row in set 0.0693 sec .. table:: .table 명령어 :widths: 30 80 ======================= === 명령어 설명 .table list 접근 가능한 테이블목록을 조회 합니다. .table info 테이블의 보관주기, partitionrange, partitionkey, partitiondate 등의 정보를 조회합니다. .table columns 테이블의 각 컬럼별 상세 정보를 조회합니다. .table schema 테이블 스키마 정보를 조회 혹은 변경 합니다. .table expire 각 테이블별 데이터의 보관 주기를 변경 합니다. .table range 각 테이블의 range를 변경 합니다. .table size 각 테이블의 용량 정보를 조회합니다. .table index 각 테이블의 인덱스 정보를 조회합니다. .table partition_info local 테이블에 생성된 partition 정보를 조회하며, 테이블이름을 명시해야 합니다. ======================= === 각 명령어는 다음과 같은 옵션이 존재합니다. .. table:: .table 명령어의 옵션 ============================== === 옵션 설명 | | 데이터베이스가 선택된 상황일 경우 | 선택된 데이터베이스에 존재하는 모든 테이블을 대상으로 조회 {table_name} | 데이터베이스가 선택된 상황일 경우 | 데이터베이스에 존재하는 특정 테이블을 대상으로 조회 \*.\* 접근 가능한 모든 테이블을 대상으로 조회 {database_name}.* 입력한 데이터베이스 이름에 존재하는 테이블을 대상으로 조회 {database_name}.{table_name} 입력한 데이터베이스, 테이블을 대상으로 조회 ============================== === 만약 데이터베이스를 선택하지 않은 상태에서 옵션을 주지 않을 경우 다음과 같은 오류 메시지가 발생하게 됩니다. .. code:: Error : -ERR must use (DB.TABLE) when no database is selected 테이블 리스트보기 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 생성된 테이블 리스트를 출력하는 명령어는 다음과 같습니다. .. code:: iplus> .table list {option} 아래 화면은 .table 명령어를 사용하여 테이블 리스트를 출력하는 예를 보여주고 있습니다. 출력된 결과에 대한 설명은 아래 표를 참조하시기 바랍니다. .. code:: iplus> .table list Ret : +OK Success DB_NAME TABLE_NAME SCOPE RAM_EXP_TIME DSK_EXP_TIME KEY_STRING PARTITION_STRING PARTITION_RANGE =============================================================================================================================== TEST LOCAL_TEST_TABLE LOCAL 30 34200 k p 10 TEST GLOBAL_TEST_TABLE GLOBAL 0 0 None None 0 =============================================================================================================================== 2 row in set 0.1517 sec .. table:: .table list 실행 결과의 컬럼 :widths: 20 80 ================== === 컬럼 설명 DB_NAME 데이터베이스 명 TABLE_NAME 테이블 명 SCOPE 테이블의 종류 (LOCAL, GLOBAL, SYSTEM) RAM_EXP_TIME 메모리 보관 주기(분) DSK_EXP_TIME 디스크 보관 주기(분) KEY_STRING partitionkey 컬럼 PARTITION_STRING partitiondate 컬럼 PARTITION_RANGE partitionrange (분) ================== === 테이블 상세 정보 보기 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ IRIS에 생성된 테이블의 상세 정보를 조회하는 명령어는 다음과 같습니다. .. code:: iplus> .table info {option} 아래는 LOCAL_TEST_TABLE 테이블의 정보를 조회하기 위하여 상기의 명령어를 실행한 예시 화면입니다. 출력된 결과에 대한 설명은 아래 표를 참조하시기 바랍니다. .. code:: iplus> .table info LOCAL_TEST_TABLE Ret : +OK Success DB_NAME TABLE_NAME SCOPE RAM_EXP_TIME DSK_EXP_TIME KEY_STRING PARTITION_STRING PARTITION_RANGE ZIP_OPTION USING_FTS ======================================================================================================================================================== TEST LOCAL_TEST_TABLE LOCAL 30 34200 k p 10 DEFAULT NO ======================================================================================================================================================== 1 row in set 0.0166 sec .. table:: .table info 실행 결과의 컬럼 :widths: 30 70 ================== === 컬럼 설명 TABLE_NAME 테이블 명 SCOPE 테이블의 종류 (LOCAL, GLOBAL, SYSTEM) RAM_EXP_TIME 메모리 보관 주기(분) DSK_EXP_TIME 디스크 보관 주기(분) KEY_STRING partitionkey 컬럼 PARTITION_STRING partitiondate 컬럼 PARTITION_RANGE partitionrange (분) USING_FTS 해당 테이블이 FTS(Full Text Search) 기능의 사용 유무 (YES or NO) ================== === 테이블 컬럼정보 조회하기 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ IRIS에 생성된 테이블의 컬럼 정보를 조회하는 명령어는 다음과 같습니다. .. code:: iplus> .table columns {option} 아래 예시는 LOCAL_TEST_TABLE 테이블의 컬럼 정보를 확인하는 방법을 보여줍니다. .. code:: iplus> .table columns LOCAL_TEST_TABLE Ret : +OK Success TABLE_CAT TABLE_SCHEM TABLE_NAME COLUMN_NAME DATA_TYPE TYPE_NAME COLUMN_SIZE BUFFER_SIZE BUFFER_LENGTH DECIMAL_DIGITS NULLABLE REMARKS COLUMN_DEF SQL_DATA_TYPE SQL_DATETIME_SUB CHAR_OCTET_LENGTH ORDINAL_POSITION IS_NULLABLE SCOPE_CATLOG SCOPE_SCHEMA SCOPE_TABLE SOURCE_DATA_TYPE IS_AUTOINCREMENT NOTINDEXED ================================================================================================================================================================================================================================================================================================================================================================================================= TEST null LOCAL_TEST_TABLE K -1 TEXT 65535 65535 null 10 1 null 0 0 65535 1 YES null null null null False False TEST null LOCAL_TEST_TABLE P -1 TEXT 65535 65535 null 10 1 null 0 0 65535 2 YES null null null null False False TEST null LOCAL_TEST_TABLE A -1 TEXT 65535 65535 null 10 1 null 0 0 65535 3 YES null null null null False False ================================================================================================================================================================================================================================================================================================================================================================================================= 3 row in set 0.0235 sec .. table:: .table columns 실행 결과의 컬럼 ====================== === 컬럼 설명 TABLE_CAT 데이터베이스 명 TABLE_SCHEM null TABLE_NAME 테이블 명 COLUMN_NAME 컬럼 명 DATA_TYPE java.sql.Types에 매핑되는 타입 TYPE_NAME 타입 명 COLUMN_SIZE 컬럼 크기 BUFFER_SIZE null BUFFER_LENGTH (사용하지 않는 컬럼) DECIMAL_DIGITS null NULLABLE null 허용 여부 REMARKS null COLUMN_DEF null SQL_DATA_TYPE (사용하지 않는 컬럼) SQL_DATETIME_SUB (사용하지 않는 컬럼) CHAR_OCTET_LENGTH null ORDINAL_POSITION 컬럼의 순서(시작 번호 1) IS_NULLABLE 컬럼 데이터의 null 포함 여부 SCOPE_CATLOG null SCOPE_SCHEMA null SCOPE_TABLE null SOURCE_DATA_TYPE null IS_AUTOINCREMENT autoincrement 컬럼 여부 NOTINDEXED fts 테이블일 경우 컬럼에 인덱스 적용 여부 ====================== === 테이블 스키마 정보 조회하기 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 각 테이블의 스키마 정보를 조회하기 위해서는 다음과 같은 명령어를 사용합니다. .. code:: iplus> .table schema {option} 아래 예시는 LOCAL_TEST_TABLE 테이블의 스키마 정보를 확인하는 방법을 보여줍니다. .. code:: iplus> .table schema LOCAL_TEST_TABLE Ret : +OK Success DB_NAME TABLE_NAME SQL_SCRIPT ============================================================================================== TEST LOCAL_TEST_TABLE CREATE TABLE LOCAL_TEST_TABLE ( K TEXT , P TEXT , A TEXT ); ============================================================================================== 1 row in set 0.1549 sec 상기 예시에서와 같이 스키마 정보에는 ramexpire 등 옵션 정보는 출력되지 않습니다. 따라서, 테이블의 옵션 정보는 .table list 명령어를 통하여 확인하여야 합니다. 테이블 파티션 정보 조회하기 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | 이 명령어는 LOCAL테이블의 파티션 정보를 조회하는 명령어입니다. | 사용할 때는 꼭 테이블이름을 명시해야 합니다. | 해당 명령어는 IRIS DB 의 부하를 줄 수 있으므로, ``--ignore-path`` 옵션을 사용하도록 권장합니다. | | **주의사항** : partition 리스트는 partition 데이터가 저장되어 있는 데이터노드 IP 별로 중복 출력될 수 있습니다. 1개 partition 데이터가 파일 1개에 모두 저장된다고 하더라도, 이중화되어 있다면 2개의 데이터노드 IP 를 가지므로 2개 레코드로 출력됩니다. | - 테이블의 전체 파티션 가져오기 .. code:: iplus> .table partition_info 테이블이름 --ignore-path LOCATION(PARTITION >= '00000000000000') - 일부 파티션 가져오기 .. code:: iplus> .table partition_info 테이블이름 --ignore-path LOCATION(PARTITION >= '20210331000000' AND PARTITION < '20210401000000' ) - 명령어 예시 .. code:: iplus> .table partition_info 테이블이름 --ignore-path LOCATION(PARTITION >= '20210331000000') Ret : +OK Success KEY PARTITION BLOCK_NUM IP ======================================================== P_K 20210331000000 1 192.168.107.4 P_K 20210331000000 1 192.168.107.3 ... 48 row in set 0.0832 sec iplus> .table partition_info LOCAL_TEST_HOST LOCATION(PARTITION >= '20210331010000') Ret : +OK Success KEY PARTITION BLOCK_NUM IP PATH ==================================================================================================================================================== P_K 20210331020000 1 192.168.107.12 /home/iris/IRIS/data/slave_disk/part00/T163/P_K/2021/03/31/T163_P_K_20210331020000_1.DAT P_K 20210331030000 1 192.168.107.12 /home/iris/IRIS/data/slave_disk/part00/T163/P_K/2021/03/31/T163_P_K_20210331030000_1.DAT ... 테이블 스키마 변경하기 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 테이블의 스키마를 수정하는 방법은 글로벌 테이블과 로컬 테이블이 상이합니다. 글로벌 테이블의 경우, 새로운 컬럼을 추가할 수 있으나, 삭제 혹은 변경은 지원하지 않습니다. 글로벌 테이블의 컬럼을 추가하는 방법은 다음과 같습니다. .. code:: iplus> ALTER TABLE {table_name} ADD COLUMN {new_column}; 로컬 테이블에서의 테이블 수정은 Dot Command를 사용하여 기존의 스키마를 새로운 스키마로 변경하는 것입니다. 만일, alter table 명령어를 이용하여 로컬 테이블을 수정하면 모든 블록 파일에 접근하여 스키마를 변경하기 때문에 시스템의 부하에 영향을 줄 수 있습니다. 따라서, 로컬 테이블에 대해서는 Dot Command를 사용하여 테이블을 수정합니다. Dot Command를 사용하여 로컬 테이블의 스키마를 변경하면, 변경 직후부터 입력되는 데이터에 대하여 변경된 스키마가 적용됩니다. 따라서, 기존 데이터의 스키마는 변경되지 않습니다. 즉, 단일 테이블명에 2개의 상이한 스키마와 데이터가 존재하게 됩니다. 이 경우에도 사용자에게는 최신의 스키마 정보만 보여집니다. 로컬 테이블에서 테이블을 수정하기 위하여 사용하는 명령어는 다음과 같습니다. .. code:: iplus> .table schema {table_name} --edit {create_query} 아래는 로컬 테이블에서 기존의 테이블 스키마를 변경하고 확인하는 예를 보여줍니다. .. code:: iplus> .table schema LOCAL_TEST_TABLE Ret : +OK Success DB_NAME TABLE_NAME SQL_SCRIPT ============================================================================================== TEST LOCAL_TEST_TABLE CREATE TABLE LOCAL_TEST_TABLE ( K TEXT , P TEXT , A TEXT ); ============================================================================================== 1 row in set 0.1437 sec iplus> .table schema local_test_table --edit CREATE TABLE LOCAL_TEST_TABLE ( K TEXT , P TEXT , A TEXT , B TEXT); Ret : +OK copy all success. 0.0602 sec iplus> .table schema LOCAL_TEST_TABLE Ret : +OK Success DB_NAME TABLE_NAME SQL_SCRIPT ====================================================================================================== TEST LOCAL_TEST_TABLE CREATE TABLE LOCAL_TEST_TABLE ( K TEXT , P TEXT , A TEXT , B TEXT); ====================================================================================================== 1 row in set 0.1607 sec 테이블의 데이터 보관주기 변경하기 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 테이블에서 데이터의 보관주기를 변경하는 명령어는 다음과 같습니다. 아래 명령어 사용 시, 데이터의 위치(램 혹은 디스크)에 따라 사용하는 옵션이 상이합니다. .. code:: iplus> .table expire {table_name} [ram|disk] {exp_time} 아래는 LOCAL_TEST_TABLE의 램 보관 주기를 기존의 30분에서 10분으로 변경하는 예를 보여주고 있습니다. .. code:: iplus> .table info local_test_table Ret : +OK Success DB_NAME TABLE_NAME SCOPE RAM_EXP_TIME DSK_EXP_TIME KEY_STRING PARTITION_STRING PARTITION_RANGE ZIP_OPTION USING_FTS ======================================================================================================================================================== TEST LOCAL_TEST_TABLE LOCAL 30 34200 k p 10 DEFAULT NO ======================================================================================================================================================== 1 row in set 0.0224 sec iplus> .table expire local_test_table ram 10 Ret : +OK copy all success. 0.0547 sec iplus> .table info local_test_table Ret : +OK Success DB_NAME TABLE_NAME SCOPE RAM_EXP_TIME DSK_EXP_TIME KEY_STRING PARTITION_STRING PARTITION_RANGE ZIP_OPTION USING_FTS ======================================================================================================================================================== TEST LOCAL_TEST_TABLE LOCAL 10 34200 k p 10 DEFAULT NO ======================================================================================================================================================== 1 row in set 0.0183 sec 테이블의 partitionrange 수정하기 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 테이블 partitionrange를 변경하는 명령어는 다음과 같습니다. .. code:: iplus> .table range {table_name} {range} 아래는 LOCAL_TEST_TABLE의 range값을 기존의 10분에서 20분으로 변경하는 예를 보여주고 있습니다. .. code:: iplus> .table info local_test_table Ret : +OK Success DB_NAME TABLE_NAME SCOPE RAM_EXP_TIME DSK_EXP_TIME KEY_STRING PARTITION_STRING PARTITION_RANGE ZIP_OPTION USING_FTS ======================================================================================================================================================== TEST LOCAL_TEST_TABLE LOCAL 10 34200 k p 10 DEFAULT NO ======================================================================================================================================================== 1 row in set 0.0197 sec iplus> .table range local_test_table 20 Ret : +OK copy all success. 0.0532 sec iplus> .table info local_test_table Ret : +OK Success DB_NAME TABLE_NAME SCOPE RAM_EXP_TIME DSK_EXP_TIME KEY_STRING PARTITION_STRING PARTITION_RANGE ZIP_OPTION USING_FTS ======================================================================================================================================================== TEST LOCAL_TEST_TABLE LOCAL 10 34200 k p 20 DEFAULT NO ======================================================================================================================================================== 1 row in set 0.0213 sec 테이블 용량정보 조회하기 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 제공되는 명령어를 이용하면 IRIS에서 사용중인 각 테이블의 사용량을 확인할 수 있습니다. 측정되는 용량은 이중화가 되어 있는 데이터 용량이며, 실시간으로 측정되는 용량이 아닙니다. 테이블의 용량 정보를 조회하는 명령어는 다음과 같습니다. 기본적으로, 각 노드별 테이블의 용량을 조회할 수 있습니다. 만일 --summary 옵션을 추가하면 전체 테이블의 용량을 조회할 수 있습니다. .. code:: iplus> .table size --summary 아래는 각 노드별 테이블의 용량을 조회하는 예와 전체 테이블의 용량을 조회하는 예를 보여주고 있습니다. .. code:: iplus> .table size Ret : +OK Success NODE_ID DB_NAME TABLE_NAME SIZE FNUM SIZE_RAM FNUM_RAM UPDATETIME ==================================================================================================== 1 TEST LOCAL_TEST_TABLE 0 0 32768 1 20180328021000 ==================================================================================================== 1 row in set 0.0668 sec iplus> .table size --summary Ret : +OK Success NODE_ID DB_NAME TABLE_NAME SIZE FNUM SIZE_RAM FNUM_RAM UPDATETIME ==================================================================================================== - TEST LOCAL_TEST_TABLE 0 0 32768 1 20180328021000 ==================================================================================================== 1 row in set 0.0713 sec .. table:: .table columns 실행 결과의 컬럼 ============== === 컬럼 설명 NODE_ID 노드 아이디 DB_NAME 데이터베이스 명 TABLE_NAME 테이블 명 SIZE 디스크에서 사용중인 용량 (byte) FNUM 디스크에 존재하는 블럭 파일 개수 SIZE_RAM 램디스크에서 사용중인 용량 (byte) FNUM_RAM 램디스크에 존재하는 블럭 파일 개수 UPDATETIME 정보 수집 시간 ============== === 테이블 삭제하기 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ IRIS에서 제공하는 테이블 삭제 방법은 일반적인 데이터베이스에서 SQL을 이용하여 테이블을 삭제하는 방법과 동일합니다. 단, IRIS의 테이블은 테라바이트 이상 빅데이터를 저장하고 있기 때문에, 테이블을 삭제한다고 하더라도, 해당 테이블의 데이터가 즉시 삭제되지 않으며, 데이터 량에 따라 일정 시간이 소요됩니다. 따라서, 테이블을 삭제한다고 하더라도 디스크의 사용량이 급격하게 줄어들지는 않습니다. IRIS에서 테이블 삭제 명령을 실행하면 다음과 같은 절차에 따라 삭제가 이루어집니다. #. 테이블(테이블명 및 스키마)을 삭제합니다. #. 마스터 노드의 데이터 위치 정보에서 해당 데이터의 위치에 삭제 표기합니다. #. BIM 프로세스가 마스터 노드의 데이터 위치 정보를 이용해 삭제할 데이터 리스트를 작성하면 PR 프로세스에서 실제 데이터를 삭제합니다. IRIS에서 테이블을 삭제하려면 아래와 같은 명령어를 사용합니다. .. code:: iplus> drop table [TABLE_NAME] 아래 화면은 특정 테이블을 삭제하는 예를 보여줍니다. .. code:: iplus> .table list Ret : +OK Success DB_NAME TABLE_NAME SCOPE RAM_EXP_TIME DSK_EXP_TIME KEY_STRING PARTITION_STRING PARTITION_RANGE ============================================================================================================================= TEST LOCAL_TEST_TABLE LOCAL 10 34200 k p 20 ============================================================================================================================= 1 row in set 0.1625 sec iplus> drop table LOCAL_TEST_TABLE; Ret : +OK Drop Table 0.2018 sec iplus> .table list Ret : +OK Success DB_NAME TABLE_NAME SCOPE RAM_EXP_TIME DSK_EXP_TIME KEY_STRING PARTITION_STRING PARTITION_RANGE ======================================================================================================================= ======================================================================================================================= 0 row in set 0.1589 sec SELECT 쿼리문 작성하기 ----------------------------------------- IRIS에서 지원하는 SELECT 쿼리문은 약간의 제약 사항을 제외하면 일반 RDBMS에서 사용하는 SELECT 문과 동일합니다. 아래는 IRIS에서 작성한 SELECT 쿼리문의 기본 형식과 사용 예입니다. SELECT 쿼리문의 syntax tree는 “sql_reference”를 참조하시기 바랍니다. .. code:: SELECT {column_name}{, column_name} FROM {table_name}; SELECT {column_name}{, column_name} from {database_name}.{table_name}; SELECT * FROM LOCAL_TEST_TABLE; SELECT sum(a) / count(a) FROM LOCAL_TEST_TABLE WHERE a > 10; IRIS에서 SELECT 쿼리문 작성 시, 주의하여야 할 제약 사항은 다음과 같습니다. - 아래 예와 같이, SELECT 문에서 기존 테이블 명을 지정하지 않고, table alias를 사용하는 경우는 지원하지 않습니다. .. code:: SELECT a.* FROM (SELECT * from X) a; - 아래 예와 같이, 여러 개의 테이블을 동시에 사용시 select절에 * 를 사용할 수 없습니다. .. code:: SELECT * FROM X, Y; INSERT 쿼리문 작성하기 ----------------------------------------- IRIS에서 지원하는 INSERT 쿼리문은 일반 RDBMS에서 사용하는 INSERT 문과 유사하지만, 테이블 생성시 지정된 partitionkey와 partitiondate의 값에 유의해야 합니다.. 아래는 IRIS에서 작성한 INSERT 쿼리문의 기본 형식과 사용 예입니다. INSERT 쿼리문의 syntax tree는 “sql_reference”를 참조하시기 바랍니다. .. code:: INSERT INTO VALUES <(value1, value2, value3,…)>; INSERT INTO LOCAL_TEST_TABLE (k, p, a) VALUES ('k2', '20110616000000', '1'); 상기의 예에서, k는 partitionkey, p는 partitiondate, a는 일반 컬럼을 의미합니다. INSERT 쿼리문을 작성할 때의 제약 사항은 다음과 같습니다. - Partitionkey로 지정된 컬럼의 값은 영문 대소문자, 숫자, (-), (_)를 조합하여 사용합니다. - Partitiondate로 지정된 컬럼의 값은 14자리의 날자 형식(yyyymmddHHMMSS)을 사용합니다. UPDATE 쿼리문 작성하기 ----------------------------------------- IRIS에서 지원하는 UPDATE 쿼리문은 일반 RDBMS에서 사용하는 UPDATE 문과 유사합니다. 아래는 IRIS에서 작성한 UPDATE 쿼리문의 기본 형식과 사용 예입니다. UPDATE 쿼리문의 syntax tree는 “sql_reference”를 참조하시기 바랍니다. .. code:: UPDATE SET WHERE ; UPDATE LOCAL_TEST_TABLE SET a = 'update'; 상기의 예는 LOCAL_TEST_TABLE의 a 컬럼의 값을 ‘update’로 변경하는 예입니다. | [주의] IRIS의 특성 상, 분산 노드에 저장된 데이터의 위치는 partitionkey와 partitiondate를 기준으로 관리합니다. 만일, 사용자가 임의로 partitionkey 혹은 partitiondate 값을 변경하면, 실제 데이터의 위치와 IRIS에서 관리하는 데이터 위치 정보간에 불일치가 일어날 수 있으며, 만일 LOCATION HINT를 사용할 경우, 데이터를 찾지 못하는 경우가 발생할 수 있습니다. 따라서, UPDATE 쿼리 사용 시, partitionkey 컬럼과 partitiondate 컬럼은 변경하지 않습니다. DELETE 쿼리문 작성하기 ----------------------------------------- IRIS에서 지원하는 DELETE 쿼리문은 일반 RDBMS에서 사용하는 DELETE 문과 유사합니다. 아래는 IRIS에서 작성한 DELETE 쿼리문의 기본 형식과 사용 예입니다. DELETE 쿼리문의 syntax tree는 “sql_reference”를 참조하시기 바랍니다. .. code:: DELETE FROM WHERE ; DELETE FROM LOCAL_TEST_TABLE WHERE a = 'update'; 상기의 예는 LOCAL_TEST_TABLE의 a 컬럼이 ‘update’인 레코드를 삭제하는 예입니다. JOIN 쿼리문 작성하기 ----------------------------------------- IRIS는 제한된 범위에서 JOIN 쿼리문 사용이 가능하도록 지원합니다. IRIS에서 JOIN 사용 시 제약사항은 다음과 같습니다. - JOIN 쿼리문에서 테이블간 JOIN 시 아래 표와 같이, 로컬 테이블간의 JOIN을 허용하지 않습니다. .. table:: IRIS 테이블간 JOIN의 use case ================== ================== ================== ================ 첫 번째 테이블 두 번째 테이블 세 번째 테이블 JOIN 가능 여부 GLOBAL GLOBAL - 가능 GLOBAL LOCAL - 가능 GLOBAL GLOBAL GLOBAL 가능 GLOBAL GLOBAL LOCAL 가능 GLOBAL LOCAL LOCAL 불가능 LOCAL LOCAL - 불가능 ================== ================== ================== ================ - INNER JOIN과 LEFT OUTER JOIN만 지원합니다. INNER JOIN 사용하기 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 아래는 IRIS에서 작성한 INNER JOIN 쿼리문의 기본 형식과 사용 예입니다. .. code:: SELECT FROM , ,… [WHERE ] …; SELECT FROM INNER JOIN [ON ] [WHERE ] …; SELECT table1.pname, table1.unit, table2.carea, table2.cname FROM table1, table2 WHERE table1.unit > 100; SELECT table1.pname, table1.unit, table2.carea, table2.cname FROM table1 INNER JOIN table2 ON table1.cid = table2.cid WHERE table1.unit > 100; | 상기의 예에서와 같이, INNER JOIN문의 작성 방법은 전형적인 SQL문에서와 동일합니다. | 만일, 상기의 첫 번째 형식과 같이 [ON ]을 사용하지 않을 경우, n * n JOIN 즉 JOIN의 결과로 table1의 레코드 수 * table2의 레코드 수 만큼의 데이터가 리턴됩니다. 이 경우, 데이터 량이 많아지게 되고, 이는 시스템 성능 저하의 원인이 될 수 있습니다. 따라서, LOCATION HINT와 WHERE 절을 적절히 사용하여 연산에 필요한 데이터를 최소화한다면 불필요한 JOIN 연산으로 인한 시스템 성능 저하를 막을 수 있습니다. | 만일, 각 노드에서 데이터 쿼리를 실행하여 얻은 중간 데이터량이 설정된 값(기본값: 노드당 쿼리문 수행 결과 데이터량이 5GB)보다 큰 경우, 메모리를 과다 점유할 수 있습니다. 따라서, 이로 인하여 발생될 수 있는 문제를 차단하기 위하여, IRIS에서 해당 작업을 강제로 종료할 수 있습니다. LEFT OUTER JOIN 사용하기 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 아래는 IRIS에서 작성한 LEFT OUTER JOIN 쿼리문의 기본 형식과 사용 예입니다. .. code:: SELECT FROM LEFT OUTER JOIN [ON ] [WHERE ] …; SELECT table1.pname, table1.unit, table2.carea, table2.cname FROM table1 LEFT OUTER JOIN table2 ON table1.cid = table2.cid WHERE table2.count = 11; | [주의] IRIS에서는 각 노드에 분산되어 저장된 파일 단위로 JOIN 연산을 수행합니다. 상기의 기본 형식에서, table1 위치에 글로벌 테이블을 지정하고 table2 위치에 로컬 테이블을 지정하여 LEFT OUTER JOIN을 실행하여 JOIN 결과값을 확인해 보면 일부 데이터가 누락되는 것으로 알 수 있습니다. 이는 글로벌 테이블의 레코드 수가 로컬 테이블의 레코드 수보다 작기 때문입니다. 따라서, LEFT OUTER JOIN을 사용할 경우, 로컬 테이블은 상기의 쿼리문 기본 형식에서 항상 table1 위치에만 사용합니다. 4.6. HINT문 작성하기 ----------------------------------------- 쿼리문이 실행될 때, IRIS 사용자는 쿼리문 외에 부가 조건을 제시함으로써 쿼리의 응답시간을 개선시킬 수 있습니다. IRIS의 특성에 맞게 최적화된 HINT 기능은 응답 속도를 높이거나, 리소스를 효율적으로 사용하는 등 다양한 용도로 활용할 수 있습니다. 예를 들어, 데이터 조회를 위한 SELECT 쿼리문을 실행할 경우, 일반적인 DBMS에서는 해당 테이블에 저장되어 있는 전체 데이터를 대상으로 조회합니다. 그러나, IRIS에서 HINT 기능을 사용하면 참조할 데이터의 범위를 한정할 수 있고, 대상 범위내의 데이터를 대상으로 조회가 이루어지기 때문에 빠른 속도로 데이터를 조회할 수 있습니다. HINT 기능은 IRIS에서 지원하는 쿼리문 중, UPDATE, DELETE, SELECT 쿼리에서 사용할 수 있습니다. HINT문의 사용 형식은 다음과 같습니다. 즉, 일반 쿼리 문 앞의 /\*와 \*/ 사이에 HINT 문을 작성합니다. .. code:: /*+ HINT-String */ Query-String 아래는 HINT 문 중에서 LOCATION HINT를 사용한 예를 보여주고 있습니다. .. code :: /*+ LOCATION (PARTITION >= '20160101000000' AND PARTITION < '20160201000000')*/ select * from table_1; 만일, 여러 개의 HINT를 같이 사용할 경우, 아래와 같이 콤마(,)로 구분하여 사용합니다. 아래는 BYPASS HINT와 LOCATION HINT를 같이 사용한 예입니다. .. code:: /*+ BYPASS, LOCATION (PARTITION >= '20160101000000' AND PARTITION < '20160201000000')*/ select * from table_1; | [주의] 로컬 테이블의 경우, 일정 기간 동안 대량의 데이터가 저장되므로, 로컬 테이블에서 데이터를 조회할 경우 조회 요구에 대한 응답에 오랜 시간이 소요되거나 timeout이 발생할 수 있습니다. 따라서, 로컬 테이블을 대상으로 데이터를 조회할 경우, 반드시 LOCANTION HINT와 함께 사용하여야 합니다. IRIS에서 지원하는 HINT문의 종류는 아래 표와 같습니다. .. table:: IRIS에서 지원하는 HINT문의 종류 ============== ========================== === HINT 명 사용 가능한 쿼리 설명 LOCATION UPDATE, DELETE, SELECT LOCAL 테이블 대상으로, 쿼리 실행 시 참조할 데이터의 범위를 설정합니다. FORMAT SELECT 쿼리 실행결과의 출력 형태를 설정합니다. 즉, 각 컬럼별로 데이터의 출력 포맷을 문자열, 정수타입, 실수타입 등으로 설정할 수 있습니다. THREAD_COUNT SELECT 쿼리 실행 시, 해당 쿼리에 대하여 동시에 실행되는 최대 프로세스의 수를 설정하여 작업 부하 및 속도를 조절합니다. BYPASS SELECT IRIS에 저장된 데이터를 summary 작업 없이 고속으로 export하고자 할 경우에 사용합니다. FORCE UPDATE, DELETE, SELECT 일부 데이터에서 쿼리오류가 발생하여도, 이를 무시하고 나머지 정상데이터를 출력합니다. SAMPLING SELECT 쿼리의 데이터를 설정한 퍼센트만큼만 샘플링하여 가져옵니다. LOCALITY SELECT 구성된 노드의 수가 크지 않은(일반적으로, 5개 노드 이하) 소규모 클러스터의 경우, 특정 노드에 부하가 집중될 수 있습니다. 따라서, 설정한 퍼센트만큼의 확률로 작업노드의 데이터를 우선 선택하여 가져옴으로써, 노드 간의 부하를 분산하는 역할을 수행합니다. ============== ========================== === LOCATION HINT문 작성하기 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LOCATION HINT는 로컬 테이블을 대상으로 쿼리 실행 시 참조할 partitionkey와 partitiondate 값의 범위를 지정하고, 해당 범위 내의 데이터를 대상으로 조회 등 일반 쿼리문을 실행합니다. 따라서, 쿼리 실행으로 인한 부하를 줄이고 쿼리 속도를 대폭 향상시킬 수 있습니다. LOCATION HINT문의 형식은 아래와 같습니다. .. code:: /*+ LOCATION ( { 참조범위 } ) */ Query 문 상기의 참조 범위에 SQL의 WHERE 절과 동일한 문법으로 조건을 설정할 수 있습니다. 여기서, 조건에 사용 가능한 컬럼은 partitionkey와 partitiondate입니다. 아래는 전형적인 LOCATION HINT 문의 사용 예를 보여줍니다. 아래 예는 table1 테이블에 대하여 SELECT 쿼리를 실행하기 위하여, partitionkey 값이 ‘key3’ 이며, partitiondate가 2016년 1월 1일부터 2016년 2월 1일 이전까지로 데이터 범위를 한정한 후 쿼리 문을 실행하는 문장을 보여줍니다. .. code:: /*+ LOCATION ( KEY = 'key3' AND PARTITION >= '20160101000000' AND PARTITION < '20160201000000' ) */ SELECT * FROM table1; FORMAT HINT문 작성하기 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FORMAT HINT문은 쿼리 실행결과의 출력 형태를 설정합니다. 즉, 각 컬럼별로 데이터의 출력 포맷을 문자열, 정수타입, 실수타입 등으로 설정할 수 있습니다. 아래의 형식과 같이, 컬럼별로 데이터의 출력 포맷을 ‘인덱스번호 = 포맷’ 형태로 정의합니다. 여기서, 인덱스 번호는 0부터 시작합니다. .. code:: /*+ FORMAT ( { 인덱스번호 } = { 포맷 }, . . . ) */ Query 문 상기의 FORMAT HINT 문을 실행할 때는 아래와 같은 몇 가지 규칙이 적용되므로, FORMAT HINT 문 사용 시 참고하시기 바랍니다. - 출력되는 결과는 기본적으로 우측에 정렬됩니다. 만일 좌측정렬을 하려면, {포맷} 부분의 %와 type 사이의 숫자 부분에 (-)를 추가합니다. 예를 들면, %-3s, %-3d, %-5.2f 등으로 사용할 수 있습니다. 단, %-03d, %-.2f 등의 예는 좌측정렬을 할 수 없습니다. - 정수 혹은 실수 타입의 경우, {포맷} 부분의 숫자가 0으로 시작하면 앞부분의 빈 공간은 0으로 채워집니다. 예를 들어, {포맷}이 %3d 인 경우, 출력 데이터는 3자리의 1, 2, 3,… 등으로 표시되지만, %03d인 경우, 001, 002, 003,… 등으로 표시됩니다. - FORMAT HINT 문에 여러 개의 포맷을 사용하는 경우, 하나의 포맷 변환이라도 실패하면 해당 포맷이 포함된 FORMAT HINT 문의 실행이 실패하게 됩니다. - 문자열 컬럼을 정수 혹은 실수로 변환할 경우, FORMAT HINT는 독립적으로 형 변환을 할 수 없으며, 반드시 SELECT 쿼리문과 함께 사용하여야 합니다. - 정수 혹은 실수의 컬럼도 FORMAT HINT문을 실행하면 문자열로 형변환됩니다. - 실수를 출력할 때, 표현할 소수점 자리보다 실제 값의 소수점 자리가 긴 경우 자동으로 반올림됩니다. 문자열 포맷의 규칙은 Python 언어에서 사용하는 문자열 포맷과 같으며, 아래 표를 참조하시기 바랍니다. .. table:: FORMAT HINT문에서의 문자열 포맷 ============== ============== === 데이터 타입 포맷 문자열 사용법 문자열 %s %{최소길이}.{최대길이}s 정수 %d %{최소길이}.{0으로 채우는 최소길이}d 실수 %f %{최소길이 (소숫점영역 포함)}.{소숫점자리 고정길이}f ============== ============== === 아래는 전형적인 FORMAT HINT 문의 사용 예를 보여줍니다. 아래 예는 ACCOUNT 테이블에 대하여 SELECT 쿼리를 실행하며, 출력되는 결과 데이터의 포맷을 지정한 것입니다. 즉, 첫 번째 컬럼인 id의 값은 3자리 숫자이며, 앞자리의 빈칸은 0으로 채워집니다. 또한, 세 번째 컬럼인 point의 값은 소수점 2번째 자리까지 표시합니다. .. code :: /*+ FORMAT‘(0=%03’d‘,2=%.2’f) */ select id, name, point from ACCOUNT; THREAD_COUNT HINT문 작성하기 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ THREAD_COUNT HINT는 쿼리 실행 시, 해당 쿼리에 대하여 동시에 실행되는 최대 프로세스의 수를 설정하여 작업 부하 및 속도를 조절합니다. THREAD_COUNT HINT문의 형식은 아래와 같습니다. .. code:: /*+ THREAD_COUNT={num} */ Query 문 | THREAD_COUNT의 값은 10에서 1,000 사이의 정수를 지정합니다. 여기서, 해당 값을 작게 설정할 경우, 쿼리의 실행 속도는 느리지만 노드의 부하를 줄일 수 있으며, 값을 높게 설정할 경우 쿼리의 실행 속도는 빠르나 노드의 부하가 증가할 수 있습니다. | 만일, 쿼리 문을 실행 시, 상기의 THREAD_COUNT HINT문을 사용하지 않으면 default값은 50으로 자동 설정됩니다. | 아래는 THREAD_COUNT HINT 문의 사용 예를 보여줍니다. 아래 예는 동시 작업 수를 10으로 지정한 예입니다. .. code:: /*+ THREAD_COUNT = 10 */ SELECT * FROM table1; BYPASS HINT문 작성하기 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ BYPASS HINT는 group by, sum, min, max 등이 포함된 merge 쿼리를 실행하지 않습니다. 즉, 각 노드에서의 쿼리 결과에 대한 summary 작업 없이 데이터를 바로 출력하기 때문에 쿼리의 응답 속도를 높일 수 있습니다. 특히, IRIS에 저장된 데이터를 고속으로 export하고자 할 경우에 사용합니다. BYPASS HINT문의 형식은 아래와 같습니다. .. code:: /*+ BYPASS */ Query 문 아래는 BYPASS HINT 문의 사용 예를 보여줍니다. .. code:: /*+ BYPASS */ SELECT * FROM table1; BYPASS HINT 문을 실행할 때는 아래와 같은 몇 가지 제약 사항이 존재하므로, BYPASS HINT 문 사용 시 참고하시기 바랍니다. - “IRIS System Overview의 3.3.3 쿼리 실행”에서 설명한 바와 같이, IRIS는 각 노드에서 데이터 쿼리를 실행한 후, 특정 노드의 UDM에서 그 결과를 취합하여 merge 쿼리를 수행합니다. 만일, group by, sum, min, max 등 summary가 필요한 쿼리문에 BYPASS HINT를 사용하면, 실제로 merge 쿼리가 실행되지 않은 결과를 제공하므로 사용자가 원하는 데이터를 제공할 수 없습니다. 따라서, BYPASS HINT는 merge 쿼리가 포함되지 않은 일반적인 SELECT문(예를 들어, SELECT from WHERE )에 사용하여야 합니다. - BYPASS HINT 문에서 사용하는 SELECT문에는 연산자(예, SELECT total/2 FROM …, SELECT sales_amount / head_count FROM … 등)를 사용할 수 없습니다. - 각 노드에서 데이터를 취합하는 과정에서 에러가 발생하면, 에러가 발생하기 이전에 취합한 데이터만 출력합니다. FORCE HINT문 작성하기 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FORCE HINT는 일부 데이터에서 쿼리오류가 발생하여도, 이를 무시하고 나머지 정상 데이터를 출력합니다. 즉, 분산 데이터 파일 중, 특정 데이터 파일에서 쿼리 실패 시에도 나머지 정상 데이터 파일에서의 쿼리 결과는 정상적으로 출력합니다. 따라서, 동일한 쿼리문을 여러 번 실행하는 경우, 다른 결과를 얻을 수 있습니다. FORCE HINT문의 형식은 아래와 같습니다. .. code:: /*+ FORCE */ Query 문 아래는 FORCE HINT 문의 사용 예를 보여줍니다. .. code:: /*+ FORCE */ SELECT * FROM table1; SAMPLING HINT문 작성하기 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SAMPLING HINT는 쿼리의 결과 데이터 중, 사용자가 설정한 비율(퍼센트)만큼만 샘플링하여 리턴합니다. 즉, 쿼리 결과의 일부만을 확인하고자 할 경우에 본 HINT문을 사용할 수 있습니다. 예를 들어, SAMPLING 값을 10으로 설정하고 실행하면, 각 노드에서 10% 만큼의 데이터를 리턴한 후, 중앙에서도 해당 데이터를 기준으로 summary하여 10%의 결과만을 리턴합니다. SAMPLING HINT문은 쿼리 결과를 앞에서부터 순차적으로 샘플링하는 것이 아니라, partitionkey와 partitiondate를 기준으로 각각 일정 비율만큼 샘플링하여 리턴합니다. 본 HINT문은 일정 시간이 소요되는 정상적인 쿼리를 실행하기 전에 쿼리 결과를 빠른 시간 내에 추정하는 등의 목적으로 사용될 수 있습니다. SAMPLING HINT문의 형식은 아래와 같습니다. 즉, 원본 데이터를 포함하는 최 하단 서브쿼리의 WHERE 절에 AND SAMPLE 조건을 추가하고, 최 상위 쿼리의 맨 마지막에 LIMT를 사용합니다. .. code:: /*+ SAMPLING = 샘플링 비율(실수형) */ SELECT ... FROM ( SELECT ... FROM
WEHRE ... AND SAMPLE ... ) WHERE ... ... LIMIT xxx ; 여기서, < 0 샘플링 비율 < 100 사용자가 정확하게 원하는 수만큼의 레코드를 리턴받고자 할 경우, 상기 형식에서와 같이 LIMIT를 사용합니다. 예를 들어, 3,000건의 데이터 중, 정확하게 100건의 레코드만 리턴받고자 할 경우, SAMPLING = 3.4로 설정하고, LIMIT 100을 추가하면 100건의 레코드만 리턴됩니다. | [주의] 만일, SELECT 문에서 GROUP BY 등 summary를 수행하면, 리턴되는 레코드의 수가 현저하게 줄어들게 됩니다. 따라서, 예를 들어 SAMPLING 비율을 50%로 설정하더라도, SELECT 문에 따라서는 단 1건의 레코드만 리턴될 수도 있습니다. LOCALITY HINT문 작성하기 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | 사용자가 요청한 쿼리문이 입력되면, 특정 데이터 노드에서 동작하는 UDM 프로세스에서 쿼리문을 분석한 후, 해당 데이터가 존재하는 각 데이터 노드에 데이터 쿼리를 요청합니다. 만일, UDM 프로세스가 동작하는 노드에 해당 데이터가 존재할 경우, 물리적으로 분리된 노드에 데이터 쿼리를 요청하는 것 보다는 UDM 프로세스가 동작하는 노드에 데이터 쿼리를 요청하여 결과를 받는 것이 쿼리 속도를 높일 수 있습니다. | LOCALITY HINT는 소규모 클러스터(일반적으로, 5개 노드 이하)에서 쿼리 속도를 높이기 위한 목적으로 사용합니다. 즉, 쿼리 조건에 해당되는 데이터가 UDM 프로세스와 동일한 노드에 존재할 경우, 지정한 비율만큼 해당 노드에서 데이터를 우선 선택하여 리턴받기 때문에 쿼리 속도를 높일 수 있습니다. | 단, 소규모 클러스터 환경에서, UDM 프로세스가 동작하는 노드에서 쿼리를 수행하면 해당 노드에 부하가 집중될 수 있습니다. 따라서, LOCALITY 범위를 작게 설정하여 작업노드의 데이터를 작게 선택하여 가져옴으로써, 노드 간의 부하를 분산시킬 수 있습니다. | LOCALITY HINT문의 형식은 아래와 같습니다. LOCALITY의 범위는 0에서 100까지 사용 가능하며, 옵션값이 0일 경우, 모든 데이터를 다른 데이터 노드에서 검색하여 가져오게 됩니다. .. code:: /*+ LOCALITY = {num} */ Query 문 아래는 LOCALITY HINT 문의 사용 예를 보여줍니다. 아래 예는 inventory_table에 저장된 데이터 중, pname 컬럼과 pstock 컬럼의 값을 출력하는 쿼리문입니다. 이때, UDM이 동작하는 노드의 블록파일에서 90%의 데이터를 리턴하며, 다른 노드의 블록파일에서 나머지(10%) 데이터를 리턴하도록 설정하였습니다. .. code:: /*+ LOCALITY = 90 */ SELECT pname, pstock FROM inventory_table; PAGE HINT문 작성하기 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ IRIS는 분산된 데이터를 처리하기 때문에 order by 구문을 사용하지 않는 이상 같은 쿼리의 결과 순서는 변경이 될 수 있습니다. 따라서 limit 명령어를 이용한 page기능을 구현이 불가능 합니다. 이를 해결하기 위해 PAGE HINT문을 제공하고 있습니다. PAGE HINT의 구문은 다음과 같습니다. .. code:: /*+ PAGE ( start_row, cnt ) */ query 아래는 LOCAL_TEST_TABLE에서 처음부터 3개의 레코드를 받아오는 PAGE HINT문의 예를 보여줍니다. .. code:: /*+ PAGE ( 1, 3 ) */ SELECT * FROM local_test_table; IRIS 지원함수 사용하기 ----------------------------------------- 다음은 IRIS에서 지원하는 SQL에서 사용 가능한 함수 및 연산자 리스트에 대하여, 글로벌 테이블과 로컬 테이블로 구분하여 지원 여부를 정리한 표입니다. 아래 표에 나열된 대부분의 함수는 일반적으로 사용되는 함수이므로 별도의 설명을 기술하지 않습니다. 단, Local Table 란에 “(설명 참조)”로 표시된 일부 항목은 분산 노드에서 일반적인 상황과 다르게 동작할 수 있으므로, 아래 해당 절에 기술한 설명을 참조하시기 바랍니다. .. table:: IRIS SQL에서 지원하는 Aggregation 함수 ============== ============== === 함수명 Global Table Local Table count() O O (설명 참조) max() O O (설명 참조) min() O O (설명 참조) sum() O O (설명 참조) ============== ============== === .. table:: IRIS SQL에서 지원하는 일반 함수 ============== ============== === 함수명 Global Table Local Table abs() O O b64d() O O ceil() O O char() O O coalesce() O O concat() O (설명 참조) O (설명 참조) date() O O datetime() O O decrypt() O O encrypt() O O floor() O O fstr() O O hex() O O ifnull() O O ifnull2() O O instr() O O julianday() O O length() O O lower() O O lpad() O O ltrim() O O nullif() O O passwd() O O power() O O quote() O O randomblob() O O replace() O O rmcar() O O rmhint() O O round() O O rpad() O O rtrim() O O sha256() O O sqrt() O O strftime() O O substr() O O time() O O to_char() O O to_date() O (설명 참조) O (설명 참조) trim() O O typeof() O O unicode() O O upper() O O zeroblob() O O ============== ============== === .. table:: IRIS SQL에서 지원하는 Paragraph ====================== ============== === Paragraph Global Table Local Table case when then end O O group by O O (설명 참조) having X X limit O (설명 참조) O (설명 참조) order by[asc, desc] O O (설명 참조) ====================== ============== === .. table:: IRIS SQL에서 지원하는 Operation ====================== ============== === Operation Global Table Local Table [=, >, <, >=, <=, <>] O O and, or, not O O between and O O distinct O O escape O (설명 참조) O (설명 참조) In O O Is null, is not null O O like O O ====================== ============== === Aggregation 함수 및 관련 paragraph 사용하기 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | 사용자가 쿼리를 요청하면, IRIS는 사용자 쿼리를 각 노드에서 개별 블록파일단위로 실행하는 데이터 쿼리, 그리고 각 노드의 쿼리 결과를 취합하여 서머리하는 merge 쿼리로 변형하여 내부적으로 처리합니다. 이는 오픈소스의 map/reduce 작업과 유사한 형태입니다. IRIS가 사용자 쿼리를 merge 쿼리와 데이터 쿼리로 변형하기 위하여 다음과 같은 규칙을 적용합니다. | Aggregation 함수(sum, min, max, count), group by, order by등이 포함된 사용자 쿼리를 로컬 테이블에 대하여 실행한다고 가정합시다. 만일, 각 노드에서 실행되는 데이터 쿼리에 aggregation 함수나 group by 등을 실행하면, 각 노드의 개별 블록파일단위로 쿼리가 실행되기 때문에 사용자 쿼리에 대하여 원하는 최종 결과를 얻을 수 없습니다. 아래는 원하는 쿼리 실행 결과를 얻기 위하여 IRIS 사용자가 작성한 쿼리의 예입니다. **부적절한 쿼리 예** 아래의 예를 전형적인 DBMS에서 실행할 경우에는 동일한 결과를 얻을 수 있습니다. 그러나, IRIS에서 실행하면 다른 결과가 출력됩니다. 따라서, IRIS에서 실행할 쿼리를 작성할 경우, 데이터 쿼리에서 실행되는 쿼리와 merge 쿼리에서 실행될 쿼리를 고려하여 작성하여야 합니다. 사용자가 아래의 첫 번째 쿼리를 요청하면, IRIS는 아래 쿼리 중에서 “(SELECT sum(a) AS a_sum FROM ONE_LOCAL_TABLE GROUP BY a)”를 각 노드에서 개별적으로 실행되는 데이터 쿼리로 인식합니다. 따라서, 최종 결과가 사용자가 원하는 결과와 다르게 됩니다. - IRIS에서 부적절한 쿼리 예 .. code:: SELECT a_sum FROM (SELECT sum(a) AS a_sum FROM ONE_LOCAL_TABLE GROUP BY a); - IRIS에서 적절한 쿼리 예 .. code:: SELECT sum(a) AS a_sum FROM ONE_LOCAL_TABLE GROUP BY a; **적절한 쿼리 예** 아래의 예를 보면, 데이터 쿼리에서는 각 노드의 블록파일에서 데이터만 SELECT한 후, merge 쿼리에서 aggregation 함수를 사용하여 서머리를 수행하므로 사용자가 원하는 결과를 얻을 수 있습니다. .. code:: SELECT sum(val), sum(val2), count(val) FROM ( SELECT val, val * val AS val2 FROM ONE_LOCAL_TABLE); 일반 함수 사용하기 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. _concat: **concat** concat 함수는 2개 컬럼의 문자열 값을 더하기 위하여 사용합니다. 사용 방법은 아래와 같습니다. 만일, 2개 컬럼 중, 한쪽의 값이 null이면 concat 함수의 결과도 null을 리턴합니다. .. code:: SELECT pnum, pname, concat(pnum || ‘-‘ || pname) id FROM product; .. _limit: **limit** limit 함수는 쿼리 실행 결과로 리턴되는 레코드의 수를 제한하기 위하여 사용합니다. IRIS에서는 아래 표와 같이 3가지 종류의 limit 문법을 지원합니다. .. table:: limit 함수의 종류 ========== === 종류 설명 limit - 각 노드에서 데이터 쿼리 실행결과로 얻은 데이터를 취합하여 merge 쿼리 실행 결과에 limit를 적용합니다. dlimit - 각 노드에서 데이터 쿼리 실행 시 limit를 적용한 후 취합합니다. - 최종 merge 쿼리 실행 시에는 limit를 적용하지 않습니다. mlimit - 상기의 limit와 dlimit를 동시에 지원합니다. - 즉, 각 노드에서 데이터 쿼리 실행 시 limit를 적용한 후, 취합하여 최종 merge 쿼리에서 다시 한번 limit을 적용합니다. ========== === .. _escape: **escape** escape 함수는 LIKE 연산에서 ‘%’ 나 ‘_’ 등 특수문자를 검색하기 위하여 사용합니다. 따라서, escape 함수는 항상 LIKE 연산 뒤에 사용합니다. 사용 방법은 다음과 같습니다. .. code:: SELECT * FROM product_table WHERE pname LIKE ‘_A_‘; .. _upper: .. _lower: **upper / lower** upper 함수는 영문 소문자를 대문자로 변환하는 함수입니다. 반대로, lower함수는 영문 대문자를 소문자로 변환합니다. 사용 방법은 다음과 같습니다. .. code:: SELECT * FROM product_table WHERE UPPER(pname) = ‘IRIS‘; .. _substr: **substr** substr 함수는 문자열을 잘라서 부분 문자열을 만들기 위하여 사용합니다. substr 함수의 형식은 다음과 같습니다. .. code:: substr(string, starting index, length) or substr(string, starting index) 상기의 substr 인자는 다음과 같은 규칙이 적용됩니다. - string 문자열을 starting index의 위치부터 length 길이만큼 잘라서 부분 문자열을 만듭니다. 만일, length 부분이 정의되어 있지 않으면 string 문자열의 끝까지 잘라서 부분 문자열을 만듭니다. - starting index의 값이 양수이면 string의 왼쪽부터 오른쪽으로 starting index를 카운트하며, 음수이면 string의 오른쪽부터 왼쪽으로 카운트합니다. - starting index는 1부터 시작하며, 0을 입력하더라도 1과 동일하게 첫 번째 글자를 가리킵니다. starting index가 음수인 경우, -1부터 시작합니다. - length의 값은 항상 자연수를 사용합니다. 만일, 사용자가 음수를 입력한 경우, substr((string, starting index)과 동일한 형태로 처리합니다. - starting index 혹은 length의 값이 string의 글자 길이를 초과하는 경우, 다음 규칙을 따릅니다. - starting index와 length가 모두 음수인 경우, 예를 들어, substr(‘123’, -4, -2)의 경우, 실패로 간주하고 전체 문자열을 반환합니다. - starting index가 음수이며 length가 양수인 경우, 예를 들어, substr(‘123’, -4, 2)의 경우, 범위에 허용되는 문자열(‘12’)을 반환합니다. - starting index가 양수이고, length가 string의 글자 길이를 초과하는 경우(예, substr(‘123’, 2, 6)), 범위에 허용되는 문자열(‘23’)을 반환합니다. - starting index가 string의 글자 길이를 초과하는 경우(예, substr(‘123’,5)), 빈 문자열(‘’)을 반환합니다. .. _length: **length** length 함수는 문자열의 길이를 출력하기 위하여 사용합니다. length 함수의 형식은 다음과 같습니다. .. code:: length(string) .. _round: **round** round 함수는 특정 컬럼의 값을 반올림하기 위하여 사용합니다. round 함수의 형식은 다음과 같습니다. .. code:: round(X, Y) round(X) 상기의 형식에서, round함수는 숫자 X를 소수점 Y+1번째 수에서 반올림합니다. round(X) 형식의 경우, 소수점 첫 번째 수에서 반올림합니다. Y의 값은 0을 포함한 자연수만 사용할 수 있으며, 자연수가 아닌 경우 0으로 처리합니다. 또한, 소수점 이하에서만 반올림이 가능합니다. .. _to_data: **to_date** to_date 함수는 특정 문자열을 date 형식으로 인식하여 1970/01/01 00:00:00 GMT 부터 해당 날짜까지 경과한 시간을 초로 환산하기 위하여 사용합니다. to_date 함수의 형식은 다음과 같습니다. .. code:: to_date(X, FORMAT) 상기의 형식에서, X에 해당되는 값을 FORMAT에 지정한 형태로 인식한 후, 1970/01/01 00:00:00 GMT 부터 해당 날짜까지 경과한 시간을 초로 환산하여 출력합니다. 아래 예는 현재시간이 2015년 1월 1일 13시 13분 30초 30 인 경우, 해당 값을 특정 컬럼에 INSERT하는 예를 보여줍니다. 이 경우, 현재 시간을 직접 입력할 수도 있지만, 아래 예와 같이 SYSDATE를 사용하면 현재시간 문자열을 출력하게 됩니다. .. code:: > insert into GLOBAL TEST TABLE (k, p, a) values ('a', SYSDATE, 1); > insert into GLOBAL TEST TABLE (k, p, a) values ('a', '20150101133030', 1); FORMAT에 해당되는 내용은 다음 표와 같습니다. .. table:: to_date 함수의 FORMAT ========== ================== === Format 설명 출력 %d day of month 00 %f fractional seconds SS.SSS %H hour 00 ~ 24 %j day of year 001 ~ 366 %J Julian day number %m month 01 ~ 12 %M minute 00 ~ 59 %s seconds since 1970-01-01 %S seconds 00 ~ 59 %w day of week 0 ~ 6 (Sunday = 0) %W week of year 00 ~ 53 %Y year 0000 ~ 9999 %% % ========== ================== === 아래는 p 컬럼의 값을 14자리 timestamp로 인식하여 1970/01/01 00:00:00 GMT 부터 경과한 시간을 초 단위로 환산하는 쿼리와 해당 쿼리의 실행 결과를 보여주는 예입니다. .. code:: >>> SELECT to_date( p, '%Y%m%d%H%M%S' ) FROM LOCAL_TEST_TABLE; TO_DATE(P, '%Y%m%d%H%M%S') ======================================================= 1355106008.0 1355106008.0 1355106008.0 .. _to_char: **to_char** to_char 함수는 날짜 형태의 문자열을 사용자가 지정한 문자열로 변환하기 위하여 사용합니다. to_char 함수의 형식은 다음과 같습니다. .. code:: to_char(X, FORMAT) 상기의 형식에서, X에 해당되는 날짜 형태(YYYYmmddHHMMSS)의 문자열을 FORMAT에 지정한 문자열로 변환합니다. 만일, X의 형식이 날짜 문자열이 아니면 에러가 발생합니다. FORMAT에 해당되는 내용은 다음 표와 같습니다. .. table:: to_char 함수에서 FORMAT의 형식 ========== === Format 설명 YYYY 년 MM 월 DD 일 HH24 시간 MI 분 SS 초 D 요일 (’1’ : ’ 일요일’, ’2’ : ’ 월요일’, … , ’7’ : ’ 토요일’) ========== === 아래는 to_char 함수를 사용한 예를 보여줍니다. .. code:: >>> SELECT to_char( p, 'YYYY year MM month DD day' ) FROM LOCAL_TEST_TABLE; TO_CHAR(P, 'YYYY year MM month DD day') ======================================================= 2011 year 06 month 16 day 2011 year 06 month 16 day .. _ifnull: **ifnull** ifnull 함수는 특정 컬럼의 값이 null인 경우, 지정한 다른 값을 출력하기 위하여 사용합니다. ifnull 함수의 형식은 다음과 같습니다. .. code:: ifnull(A, B) 상기의 형식에서, A 컬럼의 값이 null인 경우, B에 지정한 값을 리턴하고, null이 아닌 경우는 원래 값을 리턴합니다. .. _sum: **sum** sum 함수는 특정 컬럼의 값을 모두 더하기 위하여 사용합니다. sum 함수의 형식은 다음과 같습니다. .. code:: sum(X) 해당 컬럼의 값이 정수나 실수로 변환되지 않는 값(즉, 문자열)은 0으로 인식하며, 모든 값이 0을 제외한 정수인 경우에만 정수로 출력됩니다. .. _max: **max** max 함수는 특정 컬럼에서 가장 큰 값을 반환합니다. max 함수의 형식은 다음과 같습니다. .. code:: max(X) .. _min: **min** min 함수는 특정 컬럼에서 가장 작은 값을 반환합니다. min 함수의 형식은 다음과 같습니다. .. code:: min(X) .. _count: **count** count 함수는 특정 컬럼의 레코드 개수를 반환합니다. count 함수의 형식은 다음과 같습니다. .. code: count(X) count(*) count 함수는 테이블의 해당 컬럼의 NULL 이 아닌 레코드의 갯수를 반환합니다. 또한, count(*) 은 테이블의 전체 레코드 갯수를 반환합니다.