Partitioned DML은 다음과 같은 유형의 일괄 업데이트와 삭제를 위해 설계되었습니다.
- 정기적 클린업 및 가비지 컬렉션: 오래된 행을 삭제하거나 열을
NULL
로 설정하는 작업 포함 - 새 열을 기본값으로 백필:
UPDATE
문을 사용하여 현재NULL
인 새 열의 값을False
로 설정하는 작업 포함
소규모 트랜잭션 처리에는 Partitioned DML이 적합하지 않습니다. 일부 행에서 문을 실행하려면 식별 가능한 기본 키가 있는 트랜잭션 DML을 사용합니다. 자세한 내용은 DML 사용을 참조하세요.
블라인드 쓰기를 대량으로 커밋해야 하지만 원자적 트랜잭션이 필요하지 않은 경우 일괄 쓰기를 사용하여 Spanner 테이블을 일괄 수정할 수 있습니다. 자세한 내용은 일괄 쓰기를 사용하여 데이터 수정을 참조하세요.
Spanner 데이터베이스의 통계 테이블에서 활성 Partitioned DML 쿼리와 진행 상황에 대한 유용한 정보를 얻을 수 있습니다. 자세한 내용은 활성 Partitioned DML 통계를 참조하세요.
DML 및 Partitioned DML
Spanner는 DML 문에 두 가지 실행 모드를 지원합니다.
DML은 트랜잭션 처리에 적합합니다. 자세한 내용은 DML 사용을 참조하세요.
Partitioned DML은 키 공간을 분할한 후 보다 작은 범위의 개별 트랜잭션으로 파티션에 대한 문을 실행하므로 동시 트랜잭션 처리에 미치는 영향을 최소화하면서 데이터베이스 전체에 대한 대규모 작업을 가능하게 합니다. 자세한 내용은 Partitioned DML 사용을 참조하세요.
다음 표에서는 두 가지 실행 모드의 주요 차이점 몇 가지를 보여줍니다.
DML | Partitioned DML |
---|---|
WHERE 절과 일치하지 않는 행은 잠길 수 있습니다. |
WHERE 절과 일치하는 행만 잠깁니다. |
트랜잭션 크기 제한이 적용됩니다. | Spanner에서 트랜잭션 제한과 트랜잭션별 동시 실행 제한을 처리합니다. |
문이 멱등성을 가질 필요는 없습니다. | DML 문이 멱등성을 가져야 일관된 결과를 얻을 수 있습니다. |
트랜잭션 하나에 DML 및 SQL 문이 여러 개 포함될 수 있습니다. | 분할된 트랜잭션 하나에 DML 문이 하나만 포함될 수 있습니다. |
문 복잡성에 대한 제한이 없습니다. | 문이 완전히 분할 가능해야 합니다. |
사용자가 클라이언트 코드로 읽기-쓰기 트랜잭션을 생성합니다. | Spanner에서 트랜잭션을 만듭니다. |
분할 가능성 및 멱등성
Partitioned DML 문이 실행될 때는 한 파티션에 있는 행에서 다른 파티션의 행에 액세스할 수 없으며 개발자가 Spanner에서 파티션을 만드는 방식을 선택할 수 없습니다. 파티션 나누기는 확장성을 보장하지만 한편으로는 Partitioned DML 문이 완전히 분할 가능해야 함을 의미하기도 합니다. 즉, Partitioned DML 문은 일련의 문이 결합된 형태로 표현될 수 있어야 하며, 이때 각 문은 테이블의 단일 행에만 액세스하고 다른 테이블에는 액세스하지 않아야 합니다. 예를 들어 여러 테이블에 액세스하거나 자체 조인을 수행하는 DML 문은 분할할 수 없습니다. DML 문을 분할할 수 없으면 Spanner에서 BadUsage
오류를 반환합니다.
다음 DML 문은 각 문을 테이블의 단일 행에 적용할 수 있으므로 완전히 분할 가능합니다.
UPDATE Singers SET LastName = NULL WHERE LastName = '';
DELETE FROM Albums WHERE MarketingBudget > 10000;
다음 DML 문은 여러 테이블에 액세스하므로 완전히 분할 가능하지 않습니다.
# Not fully partitionable
DELETE FROM Singers WHERE
SingerId NOT IN (SELECT SingerId FROM Concerts);
네트워크 수준 재시도로 인해 Spanner에서 일부 파티션에 대해 Partitioned DML 문을 여러 번 실행할 수도 있습니다. 즉 하나의 문이 하나의 행에서 두 번 이상 실행될 수 있습니다. 따라서 결과의 일관성을 위해서는 문이 멱등성을 가져야 합니다. 멱등성을 가진 문은 단일 행에 대해 여러 번 실행되어도 결과가 동일합니다.
다음 DML 문은 멱등성을 갖습니다.
UPDATE Singers SET MarketingBudget = 1000 WHERE true;
다음 DML 문은 멱등성을 갖지 않습니다.
UPDATE Singers SET MarketingBudget = 1.5 * MarketingBudget WHERE true;
행 잠금
Spanner는 행이 업데이트 후보나 삭제 후보인 경우에만 잠금을 얻습니다. 이 동작은 WHERE
절과 일치하지 않는 행에 읽기 잠금을 적용할 수 있는 DML 실행과는 다릅니다.
실행 및 트랜잭션
DML 문의 분할 여부는 실행을 위해 선택하는 클라이언트 라이브러리 메서드에 따라 다릅니다. 각 클라이언트 라이브러리는 DML 실행용 메서드와 Partitioned DML 실행용 메서드를 별개로 제공합니다.
클라이언트 라이브러리 메서드를 한 번 호출할 때 Partitioned DML 문을 하나만 실행할 수 있습니다.
Spanner는 Partitioned DML 문을 전체 테이블에 원자적으로 적용하지 않지만, 각 파티션에 대해서는 Partitioned DML 문을 원자적으로 적용합니다.
Partitioned DML은 커밋 또는 롤백을 지원하지 않습니다. Spanner는 DML 문을 즉시 실행하고 적용합니다.
- 작업을 취소하면 Spanner는 실행 중인 파티션을 취소하며 나머지 파티션을 시작하지 않습니다. Spanner는 이미 실행된 파티션을 롤백하지 않습니다.
- 문을 실행하여 오류가 발생하면 모든 파티션에 대해 실행이 중지되며 Spanner는 전체 작업의 해당 오류를 반환합니다. 오류의 예로는 데이터 유형 제약 조건 위반,
UNIQUE INDEX
위반,ON DELETE NO ACTION
위반 등이 포함됩니다. 실행 실패 시점에 따라 일부 파티션에는 문이 성공적으로 실행되고 다른 파티션에는 문이 실행되지 않았을 수 있습니다.
Partitioned DML 문이 성공하면 Spanner에서 키 범위의 각 파티션에 대해 문을 최소 1회 이상 실행한 것입니다.
수정된 행의 개수
Partitioned DML 문은 수정된 행의 개수에 대한 하한값을 반환합니다. Spanner는 수정된 모든 행을 세지 못할 수도 있으므로 이 값은 수정된 행의 정확한 수가 아닐 수 있습니다.
트랜잭션 제한
Spanner에서 Partitioned DML 문을 실행하는 데 필요한 파티션과 트랜잭션을 만듭니다. 트랜잭션 제한이나 트랜잭션별 동시 실행 제한이 적용되지만 Spanner는 트랜잭션을 제한 이내로 유지하려고 합니다.
Spanner는 데이터베이스당 Partitioned DML 문을 최대 20,000개까지 동시에 실행할 수 있습니다.
지원되지 않는 기능
Spanner에서는 Partitioned DML의 일부 기능을 지원하지 않습니다.
INSERT
는 지원되지 않습니다.- Google Cloud 콘솔: Google Cloud 콘솔에서는 Partitioned DML 문을 실행할 수 없습니다.
- 쿼리 계획 및 프로파일링: Google Cloud CLI와 클라이언트 라이브러리에서는 쿼리 계획 및 프로파일링을 지원하지 않습니다.
- 다른 테이블 또는 같은 테이블의 다른 행에서 읽는 서브 쿼리
테이블 이동, 테이블 간에 조인이 필요한 변환과 같은 복잡한 시나리오에서는 Dataflow 커넥터를 사용하는 것이 좋습니다.
예
다음 코드 예시에서는 Albums
테이블의 MarketingBudget
열을 업데이트합니다.
C++
ExecutePartitionedDml()
함수를 사용하여 Partitioned DML 문을 실행합니다.
C#
ExecutePartitionedUpdateAsync()
메서드를 사용하여 Partitioned DML 문을 실행합니다.
Go
PartitionedUpdate()
메서드를 사용하여 Partitioned DML 문을 실행합니다.
자바
executePartitionedUpdate()
메서드를 사용하여 Partitioned DML 문을 실행합니다.
Node.js
runPartitionedUpdate()
메서드를 사용하여 Partitioned DML 문을 실행합니다.
PHP
executePartitionedUpdate()
메서드를 사용하여 Partitioned DML 문을 실행합니다.
Python
execute_partitioned_dml()
메서드를 사용하여 Partitioned DML 문을 실행합니다.
Ruby
execute_partitioned_update()
메서드를 사용하여 Partitioned DML 문을 실행합니다.
다음 코드 예시에서는 SingerId
열을 기준으로 Singers
테이블에서 행을 삭제합니다.
C++
C#
Go
자바
Node.js
PHP
Python
Ruby
다음 단계
DML을 사용하여 데이터를 수정하는 방법 알아보기
데이터 조작 언어(DML) 권장사항 알아보기
DML과 변형 비교에서 DML과 변형의 차이점에 대해 알아보기
다른 데이터 변환 시나리오에 Dataflow 커넥터를 사용 고려하기