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

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

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

예시에서 사용된 테이블

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

mytable내부 데이터화-시간으로 파티션을 나눈 테이블

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

mytable2 — 표준(파티션을 나누지 않은) 테이블

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

mycolumntablets 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) AS SELECT TIMESTAMP(“2017-05-01”), 1, “one”

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

INSERT INTO PROJECT_ID.DATASET.mytable (_PARTITIONTIME, field1, field2) AS SELECT TIMESTAMP(“2017-05-01 21:30:00”), 1, “one”

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

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

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

INSERT INTO PROJECT_ID.DATASET.mycolumntable (ts, field1) AS SELECT ts, id from PROJECT_ID.DATASET.mytable2

데이터 삭제

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

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

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

DELETE PROJECT_ID.DATASET.mytable WHERE field1 = 21 AND _PARTITIONTIME = “2017-05-01”

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

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

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

DELETE PROJECT_ID.DATASET.mycolumntable WHERE field1 = 21 AND DATE(ts) = “2017-05-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 가격을 참조하세요.

다음 단계

이 페이지가 도움이 되었나요? 평가를 부탁드립니다.

다음에 대한 의견 보내기...

도움이 필요하시나요? 지원 페이지를 방문하세요.