DML을 사용하여 파티션을 나눈 테이블 데이터 업데이트

이 페이지에서는 파티션을 나눈 테이블의 데이터 조작 언어(DML) 지원에 대해 간략히 설명합니다.

DML에 대한 자세한 내용은 다음을 참조하세요.

예시에 사용된 테이블

다음 JSON 스키마 정의는 이 페이지의 예시에 사용된 테이블을 나타냅니다.

mytable: 수집 시간으로 파티션을 나눈 테이블

    [
      {"name": "field1", "type": "INTEGER"},
      {"name": "field2", "type": "STRING"}
    ]

mytable2: 파티션을 나누지 않은 표준 테이블

    [
      {"name": "id", "type": "INTEGER"},
      {"name": "ts", "type": "TIMESTAMP"}
    ]

mycolumntable: ts TIMESTAMP 열을 사용하여 파티션이 분할된 파티션을 나눈 테이블

    [
      {"name": "field1", "type": "INTEGER"},
      {"name": "field2", "type": "STRING"}
      {"name": "field3", "type": "BOOLEAN"}
      {"name": "ts", "type": "TIMESTAMP"}
    ]

데이터 삽입

DML INSERT을 사용하여 파티션을 나눈 테이블에 행을 추가합니다.

수집-시간으로 파티션을 나눈 테이블에 데이터 삽입

DML 문을 사용하여 수집-시간으로 파티션을 나눈 테이블에 행을 추가하는 경우, 행을 추가해야 할 파티션을 지정할 수 있습니다. _PARTITIONTIME 유사 열을 사용하여 파티션을 참조합니다.

예를 들어 다음 INSERT 문은 mytable“2017-05-01”의 2017년 5월 1일 파티션에 단일 행을 추가합니다.

INSERT INTO
  project_id.dataset.mytable (_PARTITIONTIME,
    field1,
    field2)
SELECT
  TIMESTAMP("2017-05-01"),
  1,
  "one"

정확한 날짜 경계에 해당하는 타임스탬프만 사용할 수 있습니다. 예를 들어 다음 DML 문은 오류를 반환합니다.

INSERT INTO
  project_id.dataset.mytable (_PARTITIONTIME,
    field1,
    field2)
SELECT
  TIMESTAMP("2017-05-01 21:30:00"),
  1,
  "one"

파티션을 나눈 테이블에 데이터 삽입

DML을 사용하여 파티션을 나눈 테이블에 데이터를 삽입하는 것은 파티션을 나누지 않은 테이블에 데이터를 삽입하는 것과 동일합니다.

예를 들어 다음 INSERT 문은 mytable2(파티션을 나누지 않은 테이블)에서 데이터를 선택하여 파티션을 나눈 테이블 mycolumntable에 행을 추가합니다.

INSERT INTO
  project_id.dataset.mycolumntable (ts,
    field1)
SELECT
  ts,
  id
FROM
  project_id.dataset.mytable2

데이터 삭제

DML DELETE을 사용하여 파티션을 나눈 테이블에서 행을 삭제합니다.

수집-시간으로 파티션을 나눈 테이블에서 데이터 삭제

다음 DELETE 문은 field121mytable의 2017년 6월 1일 파티션("2017-06-01")에서 모든 행을 삭제합니다. _PARTITIONTIME 유사 열을 사용하여 파티션을 참조합니다.

DELETE
  project_id.dataset.mytable
WHERE
  field1 = 21
  AND _PARTITIONTIME = "2017-06-01"

파티션을 나눈 테이블에서 데이터 삭제

DML을 사용하여 파티션을 나눈 테이블에서 데이터를 삭제하는 것은 파티션을 나누지 않은 테이블에서 데이터를 삭제하는 것과 동일합니다.

예를 들어 다음 DELETE 문은 field121mycolumntable의 2017년 6월 1일 파티션("2017-06-01")에서 모든 행을 삭제합니다.

DELETE
  project_id.dataset.mycolumntable
WHERE
  field1 = 21
  AND DATE(ts) = "2017-06-01"

데이터 업데이트

UPDATE을 사용하여 파티션을 나눈 테이블의 행을 업데이트합니다.

수집 시간으로 파티션을 나눈 테이블에서 데이터 업데이트

다음 UPDATE 문은 한 파티션에서 다른 파티션으로 행을 이동합니다. field121mytable의 2017년 5월 1일 파티션(“2017-05-01”)에 있는 행이 2017년 6월 1일 파티션(“2017-06-01”)으로 이동합니다.

UPDATE
  project_id.dataset.mytable
SET
  _PARTITIONTIME = "2017-06-01"
WHERE
  _PARTITIONTIME = "2017-05-01"
  AND field1 = 21

파티션을 나눈 테이블에서 데이터 업데이트

DML을 사용하여 파티션을 나눈 테이블에서 데이터를 업데이트하는 것은 파티션을 나누지 않은 테이블에서 데이터를 업데이트하는 것과 동일합니다. 예를 들어 다음 UPDATE 문은 한 파티션에서 다른 파티션으로 행을 이동합니다. field121mytable의 2017년 5월 1일 파티션(“2017-05-01”)에 있는 행이 2017년 6월 1일 파티션(“2017-06-01”)으로 이동합니다.

UPDATE
  project_id.dataset.mycolumntable
SET
  ts = "2017-06-01"
WHERE
  DATE(ts) = "2017-05-01"
  AND field1 = 21

MERGE 문 사용

DML MERGE을 사용하여 파티션을 나눈 테이블의 INSERT, UPDATE, DELETE 작업을 하나의 문으로 결합하고 이를 원자적으로 수행합니다.

MERGE 문을 사용할 때 파티션 프루닝

파티션을 나눈 테이블에 대해 MERGE 문을 실행하는 경우 _PARTITIONTIME 유사 열(수집 시간으로 파티션을 나눈 테이블의 경우)을 사용하거나 날짜 또는 타임스탬프 열(파티션을 나눈 테이블의 경우)을 사용하여 문과 관련된 파티션을 제한할 수 있습니다. 파티션을 프루닝하면 비용이 줄어들고 쿼리 성능이 향상됩니다.

서브 쿼리 필터, search_condition 필터, merge_condition 필터 위치에서 파티션 프루닝 조건을 사용할 수 있습니다.

아래의 각 예시는 _PARTITIONTIME 유사 열을 사용하여 수집-시간으로 파티션을 나눈 테이블을 쿼리합니다.

서브 쿼리를 사용하여 소스 데이터 필터링

서브 쿼리에서 필터를 사용하여 파티션을 프루닝할 수 있습니다. 예를 들어 다음 MERGE 문에서 소스 테이블에 있는 '2018-01-01' 파티션의 행만 스캔됩니다.

MERGE dataset.target T
USING (SELECT * FROM dataset.source WHERE _PARTITIONTIME = '2018-01-01') S
ON T.c1 = S.c1
WHEN MATCHED THEN
  DELETE

when_clausesearch_condition에서 필터 사용

쿼리 최적화 도구는 search_condition에서 필터를 사용하여 파티션을 프루닝합니다. 예를 들어 다음 MERGE 문에서 '2018-01-01', '2018-01-02', '2018-01-03' 파티션에 있는 행만 대상 테이블에서 스캔됩니다.

MERGE dataset.target T
USING dataset.source S
ON T.c1 = S.c1
WHEN MATCHED AND T._PARTITIONTIME = '2018-01-01' THEN
  UPDATE SET c1 = S.c1
WHEN MATCHED AND T._PARTITIONTIME = '2018-01-02' THEN
  UPDATE SET c1 = c1 + 10
WHEN NOT MATCHED BY SOURCE AND T._PARTITIONTIME = '2018-01-03' THEN
  DELETE

다음 예시에서 WHEN NOT MATCHED BY SOURCE 절에는 대상 테이블의 모든 데이터가 필요합니다. 그 결과, 모든 파티션이 스캔되고 모든 파티션에서 읽은 바이트에 대해 비용이 청구됩니다.

MERGE dataset.target T
USING dataset.source S
ON T.c1 = S.c1
WHEN MATCHED AND T._PARTITIONTIME = '2018-01-01' THEN
  UPDATE SET c1 = S.c1
WHEN NOT MATCHED BY SOURCE THEN
  UPDATE SET c1 = c1 + 1

일반적으로 WHEN NOT MATCHEDWHEN NOT MATCHED BY SOURCE 절을 함께 사용하면 BigQuery는 소스와 대상 테이블 간에 FULL OUTER JOIN을 한다고 가정합니다. 파티션은 일반적으로 FULL OUTER JOIN에서 잘라낼 수 없습니다. 그러나 상수 거짓 조건자를 사용하면 파티션 프루닝에 필터 조건을 사용할 수 있습니다. 다음 쿼리는 파티션 프루닝을 사용하여 대상 및 소스 테이블 모두에서 '2018-01-01' 파티션만 스캔합니다.

MERGE dataset.target T
USING dataset.source S
ON FALSE
WHEN NOT MATCHED AND _PARTITIONTIME = '2018-01-01' THEN
  INSERT(c1) VALUES(c1)
WHEN NOT MATCHED BY SOURCE AND _PARTITIONTIME = '2018-01-01' THEN
  DELETE

merge_condition에서 필터 사용

쿼리 최적화 도구는 merge_condition에서 필터를 사용하여 파티션을 프루닝합니다. 예를 들어, 다음 쿼리는 대상 및 소스 테이블 모두에서 '2018-01-01' 파티션만 스캔합니다.

MERGE dataset.target T
USING dataset.source S
ON T.c1 = S.c1 AND
  T._PARTITIONTIME = '2018-01-01' AND
  S._PARTITIONTIME = '2018-01-01'
WHEN MATCHED THEN
  UPDATE SET c1 = S.c1

이 예시에서 merge_condition은 소스와 대상 테이블을 조인하기 위한 조건자로 사용됩니다. 쿼리 최적화 도구는 조건자 푸시다운을 사용하거나 사용하지 못할 수 있습니다(조인 유형에 따라 다름).

다음 예시에서 파티션 필터는 테이블에 직접 적용할 수 없는 조인 조건의 조건자이므로, MERGE 문은 파티션 프루닝을 허용하지 않습니다.

MERGE dataset.target T
USING dataset.source S
ON T.c1 = S.c1 AND T._PARTITIONTIME = '2018-01-01'
WHEN NOT MATCHED BY SOURCE THEN
  UPDATE SET c1 = S.c1

제한사항

DML 제한에 대한 자세한 내용은 DML 페이지의 제한사항을 참조하세요.

할당량

DML 할당량 정보에 대한 자세한 내용은 할당량 및 한도 페이지의 DML 문을 참조하세요.

가격 책정

DML 가격 정보는 파티션을 나눈 테이블의 DML 가격을 참조하세요.

다음 단계