콘텐츠로 이동

SELECT

SELECT#

Altibase 데이터베이스 링크를 사용해서 원격 데이터베이스의 객체를 조회(SELECT)하는 방법은 위치 표시자('@')를 사용하거나 pass-through 방식을 사용하는 두 가지가 있다.

Altibase 데이터베이스 링크는 pass-through 스타일의 REMOTE_TABLE 키워드를 사용할 것을 권장하고 있으며, 위치 표시자('@')는 이전 버전과의 호환성을 위해 지원한다.

두 방식 모두 FROM 절에서만 데이터베이스 링크를 사용할 수 있다.

SELECT절에서 사용하는 문자열 표기법에 대한 자세한 설명은 General Reference"문자열 표기"를 참조한다.

위치 표시자#

위치 표시자 '@'를 사용하는 구문은 이전 버전과의 호환성을 유지하기 위해 지원된다.

위치 표시자를 사용하는 방법은 아래의 예제와 같이 '@' 기호를 사용하여 해당 객체가 원격 서버에 존재하는 객체임을 표시하는 것이다.

SELECT * FROM t1@link1;

위치 표시자가 포함된 질의는 이전 버전과 마찬가지로 원격 서버에서 테이블의 모든 레코드를 로컬 서버로 가져온다. 따라서, 질의의 성격에 따라 REMOTE_TABLE 키워드를 사용하는 것이 처리 속도를 높일 수 있다.

예를 들어, 아래과 같이 위치 표시자를 사용한 질의는 원격 테이블의 모든 레코드를 로컬 서버로 가져오기 때문에, 네트워크 비용과 로컬 서버의 연산 비용, 그리고 경우에 따라 발생하는 디스크 I/O 비용까지 추가로 수반된다. 그러나, REMOTE_TABLE 키워드를 사용하면, 원격 서버에서 질의를 처리하고 로컬 서버는 결과로 하나의 레코드만 가져오기 때문에, 성능면에서 REMOTE_TABLE 키워드를 사용하는 것이 더 효과적이다.

테이블 명: T1
테이블 스키마:
C1 VARCHAR(1024),
C2 VARCHAR(1024),
C3 VARCHAR(1024),
...
C50 INTEGER,
...
C100 VARCHAR(1024),
전체 레코드 수: 1,000,000 (c50 칼럼값이 50 인 레코드는 1건)
위치 표시자 사용:#
SELECT c50, c100 FROM t1@link1 WHERE c50 = 50;
REMOTE_TABLE 키워드 사용:#
SELECT * FROM REMOTE_TABLE( link1, 'select c50, c100 from t1 where c50 = 50' );

결론적으로, 데이터베이스 링크를 사용하여 동일한 결과를 가져오는 질의의 경우, 위치 표시자보다 REMOTE_TABLE 키워드를 사용할 것을 권장한다.

예제

<질의 1> 위치 표시자를 사용해서 link1이 가리키는 원격 서버에 존재하는 t1 테이블 전체를 조회하라.

SELECT * FROM t1@link1;

<질의 2> 위치 표시자를 사용해서 원격 테이블의 a1, a2 칼럼을 조회하라.

SELECT a1, a2 FROM ( SELECT * FROM t1@link1 );

REMOTE_TABLE#

pass-through 방식의 REMOTE_TABLE 키워드를 사용해서 원격 서버에서 SELECT 문을 수행할 수 있다.

REMOTE_TABLE 키워드를 사용하여 원격 서버에서 질의를 수행하면, 질의 결과가 메모리 버퍼에 저장된다. 저장된 질의 결과는 질의 처리기에 전달된 후 삭제된다. 만약 JOIN 연산과 같이 삭제된 결과에 반복적으로 접근해야하는 질의가 있다면, 원격 서버에서 질의를 다시 수행해야 한다.

REMOTE_TABLE 키워드를 사용하는 문법은 아래와 같다.

REMOTE_TABLE (
    dblink_name     IN VARCHAR,
    statement_text  IN VARCHAR )
  • dblink_name: 데이터베이스 링크 객체의 이름
  • statement_text: 원격 서버에서 수행할 SELECT 문

예제

<질의 1> REMOTE_TABLE 키워드를 사용해서 link1이 가리키는 원격 서버에 존재하는 t1 테이블 전체를 조회하라.

SELECT * FROM REMOTE_TABLE( link1, 'select * from t1' );

<질의 2> REMOTE_TABLE 키워드를 사용해서 원격 테이블의 a1, a2 칼럼을 조회하라.

SELECT * FROM REMOTE_TABLE( link1, 'select a1, a2 from t1' );

REMOTE_TABLE_STORE#

Altibase는 REMOTE_TABLE 키워드로 원격에서 질의 수행한 결과를 반복적으로 접근할 필요가 있을 때, 수행 결과를 디스크 임시 테이블에 저장하여 반복적으로 접근할 수 있도록 한다.

WHERE 절#

데이터베이스 링크를 이용하여 원격 서버에 질의하는 경우에도 지역 서버에서 SELECT 문으로 질의할 때와 같은 방법으로 WHERE 절을 사용할 수 있다.

단, WHERE 절에는 위치 표시자 또는 REMOTE_TABLE 키워드의 사용이 허용되지 않으므로, FROM 절에 별칭(alias)을 명시하여 WHERE 절에서는 이 별칭을 사용하도록 한다.

예제

<질의 1> link1이 가리키는 원격 서버의 t1테이블에서 칼럼 a1의 값이 100보다 큰 행을 검색하라.

SELECT * FROM REMOTE_TABLE( link1, 'select * from t1 where a1 > 100' );

또는

SELECT * FROM REMOTE_TABLE( link1, 'select * from t1' ) t1_alias
 WHERE t1_alias.a1 > 100;

또는

SELECT * FROM t1@link1 WHERE a1 > 100;

<질의 2> link1이 가리키는 원격 서버의 emp2 테이블과 지역 서버의 emp1 테이블에 저장된 모든 사원 중, rnd 부서에 근무하는 사원의 이름을 검색하라.

SELECT emp_name
FROM ( SELECT emp_no, emp_name FROM emp1
    UNION ALL
    SELECT emp_no, emp_name FROM REMOTE_TABLE( link1, 'select emp_no, emp_name from emp2' ) ) v1,
    dept
WHERE v1.emp_no = dept.emp_no AND dept.dept_name = 'rnd';

또는

SELECT emp_name
FROM ( SELECT emp_no, emp_name FROM emp1
    UNION ALL
    SELECT emp_no, emp_name FROM emp2@link1 ) v1,
    dept
WHERE v1.emp_no = dept.emp_no AND dept.dept_name = 'rnd';

그 외의 SELECT 기능#

데이터베이스 링크는 SELECT구문에 조인(join), 부질의(subquery), 집합 연산자(set operators), 집계 함수(aggregation functions)의 사용을 지원한다. 또한 DDL 또는 DML구문 내에 부질의 형태로 SELECT 문이 있는 경우, 이 부질의 구문에도 데이터베이스 링크를 사용할 수 있다.

예제

<질의 1> link1이 가리키는 원격 서버의 t1테이블의 a1칼럼에서 중복을 제거한 값을 검색하라.

SELECT * FROM REMOTE_TABLE( link1, 'select distinct a1 from t1' );

또는

SELECT DISTINCT a1 FROM t1@link1;

<질의 2> link1이 가리키는 원격 서버의 t_member 테이블과 t_dept 테이블을 조인하여 전체 사원의 부서를 알아내고, 부서 ID가 0보다 크거나 같은 값을 갖는 부서들을 부서 ID 별로 묶어 각 부서의 사원 수, 평균 나이를 구하라.

SELECT t1.dept_id, COUNT(*), AVG(age)
FROM REMOTE_TABLE( link1, 'select * from t_member' ) t1,
   REMOTE_TABLE( link1, 'select * from t_dept' ) t2,
WHERE t1.dept_id = t2.dept_id
GROUP BY t1.dept_id
HAVING t1.dept_id >= 0;

또는

SELECT t1.dept_id, COUNT(*), AVG(age)
FROM t_member@link1 t1,
   t_dept@link1 t2
WHERE t1.dept_id = t2.dept_id
GROUP BY t1.dept_id
HAVING t1.dept_id >= 0;

<질의 3> link1이 가리키는 원격 서버의 t_member와 t_dept 테이블을 조인하여 전체 사원을 알아내고, 이 사원들 중 나이가 30세보다 작은 사원 중에서 ID가 큰 순으로 세 명의 사원을 뽑아 이름, 나이, 전체 사원의 나이의 합을 구하라.

SELECT t1.name, t1.age
    ( SELECT * FROM REMOTE_TABLE( link1, 'select sum(age) from t_member' ) ) sum
FROM REMOTE_TABLE( link1, 'select dept_id, member_id, dept_name, age from t_member where age < 30' ) t1,
   REMOTE_TABLE( link1, 'select dept_id, dept_name, from t_dept' ) t2
WHERE t1.dept_id = t2.dept_id AND t1.age < 30
ORDER BY t1.member_id DESC LIMIT 3;

또는

SELECT t1.name, t1.age
    ( SELECT SUM(age) FROM t_member@link1 ) sum
FROM t_member@link1 t1,
    ( SELECT dept_name, dept_id FROM t_dept@link1 ) t2
WHERE t1.dept_id = t2.dept_id AND t1.age < 30
ORDER BY t1.member_id DESC LIMIT 3;

<질의 4> link1이 가리키는 원격 서버의 t2 테이블에서 이름과 나이를 가져와서 지역 서버의 t1테이블에 삽입하라.

INSERT INTO t1 SELECT * FROM REMOTE_TABLE( link1, 'select name, age from t2' );

또는

INSERT INTO t1 SELECT name, age FROM t2@link1;