Keyboard shortcuts

Press ← or → to navigate between chapters

Press ? to show this help

Press Esc to hide this help

JDBC 동기화의 증분 처리와 병렬 쿼리

JDBC 동기화가 이미 안정적으로 끝난다면 성능 설정을 바꿀 필요는 없습니다. 새 동기화를 만들거나 실행이 너무 오래 걸리고 불안정할 때는 먼저 증분 수집으로 읽는 양을 줄이고, 그것만으로 부족하면 SQL 쿼리 병렬화를 검토합니다.

증분 동기화의 상태와 출력

일반 배치 동기화는 조건에 맞는 원천 행을 매번 읽습니다. 증분 동기화는 이전 수집 상태를 저장하여 그 이후의 행을 가져옵니다. 출력 트랜잭션은 APPEND로 구성해야 기존에 수집한 행을 덮어쓰지 않습니다.

증분 상태는 열과 초기값으로 구성됩니다. SQL의 커서 바인딩 위치 ?에는 첫 실행 때 초기값이 들어가고, 이후에는 수집한 증분 열의 최댓값으로 갱신된 상태가 들어갑니다. 커서 바인딩용 ?는 하나만 사용할 수 있습니다.

새로 수집해야 하는 행의 증분 값은 이전 커서보다 커야 합니다. 행이 생성된 뒤 바뀌지 않는 테이블은 증가하는 ID나 생성 시각을 사용할 수 있습니다. 기존 행을 수정하는 테이블은 수정할 때마다 증가하는 update_time 같은 열이 필요합니다. 생성 ID나 insert_time만 쓰면 기존 행의 수정을 놓칩니다.

설정 순서와 초기값의 경계

  1. 대상 동기화에서 미리보기를 성공시킵니다. 새로 만들거나 복제한 동기화는 먼저 쿼리에서 ?를 제외하고 미리봅니다.
  2. 트랜잭션 유형을 APPEND로 설정합니다.
  3. Incremental에서 Enable을 선택합니다. 미리보기가 성공해야 열과 초기값 설정이 표시됩니다.
  4. 증분 열과 쿼리의 비교 연산에 맞는 초기값을 설정합니다.
  5. SQL에 커서 바인딩 ?를 추가합니다.

초기값과 비교 연산을 함께 판단해야 합니다. id > ?이고 이전에 수집한 최대 ID가 1999라면 초기값 1999가 ID 2000부터 포함합니다. 초기값을 2000으로 올리면 ID 2000 자체를 건너뜁니다. >=를 사용하면 경계 값을 포함하지만 이후 실행에서도 저장된 최대값의 행을 다시 읽을 수 있습니다.

아직 수집한 행이 없다면 원하는 첫 행보다 작은 초기값을 사용합니다. 예를 들어 모든 대상 값이 양수일 때 0을 사용할 수 있습니다. 날짜 초기값으로 01/01/1970을 선택하는 경우에도 쿼리의 > 또는 >=가 그 날짜 자체를 포함하는지 구분합니다.

수정 가능한 테이블 예제

가상 테이블 employees를 다음 쿼리와 SNAPSHOT으로 수집한다고 가정합니다.

SELECT
    *
FROM
    employees

시점 T1의 값은 다음과 같습니다.

idnamesurnameupdate_timeinsert_time
1JaneSmith14788622051478862205
2ErikaMustermann14788622461478862246

T2에는 Jane의 성이 바뀌고 Juan이 추가됩니다.

idnamesurnameupdate_timeinsert_time
1JaneDoe14788624521478862205
2ErikaMustermann14788622461478862246
3JuanPerez14788624381478862438

증분 열은 update_time을 사용합니다. T1에서 최대값 1478862246까지 수집했다면 아래의 엄격한 > 조건에는 초기값 1478862246을 지정합니다. 출력은 APPEND로 바꿉니다.

SELECT
    *
FROM
    employees
WHERE
    update_time > ?

이 실행은 수정된 Jane과 새 Juan을 가져옵니다. 이전 Jane 행은 APPEND 데이터셋에 남으므로 동일한 직원의 여러 버전이 존재합니다. 최신 상태만 필요하면 후속 변환에서 업무 키별로 최신 update_time의 행을 선택해야 합니다. 증분 수집 자체가 기존 행을 제자리에서 갱신하거나 중복을 제거하지는 않습니다.

병렬 쿼리 분할

병렬화 옵션은 SQL을 여러 쿼리로 나누어 원천 데이터베이스에 동시에 실행합니다. 분할 열은 숫자 열 또는 숫자를 반환하는 식을 사용하며, 값이 가능한 한 고르게 분포하는 대상을 선택합니다.

힌트의미
FORCED_PARALLELISM_COLUMN(id)분할 기준 숫자 열 또는 식을 지정합니다.
FORCED_PARALLELISM_SIZE(4)일반 값의 분할 수를 지정합니다. NULL 전용 쿼리가 추가되어 이 예에서는 총 5개가 동시에 실행됩니다.
ALREADY_HAS_WHERE_CLAUSE(FALSE)원래 WHERE가 없으므로 분할 조건을 위한 WHERE를 새로 만듭니다.
ALREADY_HAS_WHERE_CLAUSE(TRUE)기존 WHERE에 분할 조건을 AND로 추가합니다.

원천 테이블이 실시간으로 갱신된다면 서로 다른 조회 시각 때문에 분할 결과의 일관성이 달라질 수 있습니다. 쿼리를 여러 개로 나눴다는 사실만으로 하나의 일관된 시점의 데이터를 읽는다고 가정하지 않습니다.

두 분할과 NULL 전용 쿼리 예제

가상 employees 테이블에 다음 행이 있다고 가정합니다.

idnamesurname
1JaneSmith
2ErikaMustermann
3JuanPerez
NULLMaryWatts

일반 쿼리는 전체 테이블을 한 번에 읽습니다.

SELECT
    id, name, surname
FROM
    employees

다음 설정은 값 분할 2개와 NULL 전용 쿼리 1개를 만듭니다.

SELECT
    /* FORCED_PARALLELISM_COLUMN(id), FORCED_PARALLELISM_SIZE(2) */
    id, name, surname
FROM
    employees
/* ALREADY_HAS_WHERE_CLAUSE(FALSE) */

생성되는 쿼리와 해당 행은 다음과 같습니다.

SELECT id, name, surname
FROM employees
WHERE id % 2 = 1
idnamesurname
1JaneSmith
3JuanPerez
SELECT id, name, surname
FROM employees
WHERE id % 2 = 0
idnamesurname
2ErikaMustermann
SELECT id, name, surname
FROM employees
WHERE id % 2 IS NULL
idnamesurname
NULLMaryWatts

OR 조건은 괄호로 묶기

기존 WHERE에 OR가 있으면 전체 조건을 괄호로 묶습니다. 예를 들어 숫자 열 col1, 출력 열 col2 및 Boolean 조건 열 condition1, condition2가 있는 가상 테이블 tbl은 다음과 같이 구성합니다.

SELECT
    /* FORCED_PARALLELISM_COLUMN(col1), FORCED_PARALLELISM_SIZE(32) */
    col1,
    col2
FROM
    tbl
WHERE
    (condition1 = TRUE OR condition2 = TRUE)
/* ALREADY_HAS_WHERE_CLAUSE(TRUE) */

분할 조건은 기존 조건 뒤에 AND로 붙습니다. 괄호가 없으면 condition1 OR condition2 AND 분할조건이 condition1 OR (condition2 AND 분할조건)으로 해석되어 첫 번째 조건을 만족하는 행이 여러 분할에 포함될 수 있습니다.

실제 실행 쿼리와 커서 누락, 시각 정밀도 및 NULL 오류는 동기화 문제 해결에서 확인합니다.