캐시 처리된 쿼리 결과 사용

이 문서는 BigQuery에서 캐시 처리된 결과를 사용하는 방법을 설명합니다.

개요

BigQuery는 모든 쿼리 결과를 테이블에 작성합니다. 이 테이블은 사용자(대상 테이블)에 의해 명시적으로 식별된 테이블이거나 캐시 처리된 임시 결과 테이블일 수 있습니다. 캐시 처리된 임시 결과 테이블은 사용자 및 프로젝트별로 유지관리됩니다. 임시 테이블에서는 스토리지 비용이 발생하지 않지만, 쿼리 결과를 영구 테이블에 쓰면 데이터 저장 요금이 청구됩니다.

대화형 및 일괄 쿼리가 모두 포함된 모든 쿼리 결과가 일부 예외를 제외하고 약 24시간 동안 임시 테이블에 캐시 처리됩니다.

제한사항

쿼리 캐시 사용 시 다음 제한사항이 적용됩니다.

  • 중복 쿼리를 실행하면 BigQuery가 캐시 처리된 결과를 다시 사용하려고 시도합니다. 캐시에서 데이터를 검색하려면 중복 쿼리 텍스트가 원본 쿼리와 정확하게 같아야 합니다.
  • 쿼리 결과를 캐시 처리된 결과 테이블에 유지하려면 결과 집합이 최대 응답 크기보다 작아야 합니다. 큰 결과 집합 관리에 대한 자세한 내용은 큰 쿼리 결과 반환을 참조하세요.
  • DML 문을 포함한 캐시 처리된 결과 테이블은 타겟팅할 수 없습니다.
  • 현재 시맨틱스에서 허용되더라도 종속 작업의 입력으로 캐시 처리된 결과를 사용하지 않는 것이 좋습니다. 예를 들어 캐시 테이블의 결과를 검색하는 쿼리 작업을 제출해서는 안 됩니다. 대신 이름이 지정된 대상 테이블에 결과를 작성합니다. 데이터세트 수준의 defaultTableExpirationMs 속성과 같은 기능을 사용하면 지정된 기간 후에 데이터가 자동으로 만료되어 간편하게 정리할 수 있습니다.

가격 책정 및 할당량

캐시 처리된 결과 테이블에서 쿼리 결과를 검색하면 작업 통계 속성 statistics.query.cacheHittrue로 반환되며 쿼리 요금이 청구되지 않습니다. 캐시 처리된 결과를 사용하는 쿼리에는 요금이 청구되지 않지만 BigQuery 할당량 정책이 쿼리에 적용됩니다. 비용이 절감뿐만 아니라 BigQuery에서 결과 집합을 계산할 필요가 없으므로 캐시 처리된 결과를 사용하는 쿼리 속도가 현저히 빠릅니다.

쿼리 캐싱 예외

다음과 같은 경우 쿼리 결과가 캐시 처리되지 않습니다.

  • 대상 테이블이 작업 구성, Cloud Console, 기본 웹 UI, 명령 줄 또는 API에 지정된 경우
  • 전에 결과가 캐시 처리된 후로 참조된 테이블 또는 논리 뷰가 하나라도 변경된 경우
  • 새 행이 도착하지 않았더라도 쿼리에서 참조하는 테이블 중 하나에서 최근 스트리밍 삽입을 수신한 경우(스트리밍 버퍼가 테이블에 연결됨)
  • 쿼리에서 날짜 및 시간 함수(예: CURRENT_TIMESTAMP()NOW()) 등의 비확정 함수를 사용하며 CURRENT_USER()와 같은 다른 함수에서 쿼리 실행 시기에 따라 다른 값을 반환하는 경우
  • 와일드 카드를 사용해 여러 테이블을 쿼리하는 경우
  • 캐시 처리된 결과가 만료된 경우 - 일반적인 캐시 수명은 24시간이지만 결과를 캐시 처리하는 것이 최선이므로 더 일찍 무효화될 수 있습니다.
  • 외부 데이터 소스를 대상으로 쿼리를 실행하는 경우

캐시 처리된 결과 저장 방식

쿼리를 실행하면 '익명 데이터세트'라고 하는 특수한 데이터세트에 캐시 처리된 임시 결과 테이블이 생성됩니다. IAM 리소스 계층 모델에서 권한(프로젝트 및 조직 권한)을 상속하는 정규화 데이터세트와 달리 익명 데이터세트에 대한 액세스는 데이터세트 소유자로 제한됩니다. 익명 데이터세트의 소유자란 캐시 처리된 결과가 생성된 쿼리를 실행한 사용자를 말합니다.

익명 데이터세트를 만들 때는 쿼리 작업을 실행하는 사용자에게 익명 데이터세트에 대한 bigquery.dataOwner 액세스 권한이 명시적으로 부여됩니다. bigquery.dataOwner 액세스 권한이 있으면 쿼리 작업을 실행한 사용자만 데이터세트를 완전히 제어할 수 있습니다. 여기에는 익명 데이터세트에서 캐시 처리된 결과 테이블에 대한 완전한 제어도 포함됩니다. 쿼리 결과를 공유할 생각이라면 익명 데이터세트에 저장된 캐시 처리된 결과를 사용하지 마세요. 대신 이름이 지정된 대상 테이블에 결과를 기록하세요.

쿼리를 실행하는 사용자가 데이터세트 및 캐시 처리된 결과 테이블에 대한 모든 액세스 권한을 가지고 있지만 이를 종속 작업의 입력으로 사용하는 것이 좋습니다.

익명 데이터세트 이름은 밑줄로 시작됩니다. 따라서 데이터세트가 Cloud Console 및 기본 BigQuery 웹 UI의 데이터세트 목록에 표시되지 않습니다. CLI 또는 API를 사용하여 익명 데이터세트를 나열하고 익명 데이터세트 액세스 제어를 감사할 수 있습니다.

캐시 처리된 결과 검색 중지

캐시 처리된 결과 사용 옵션에서는 쿼리되는 테이블이 변경되지 않은 한, 이전에 실행된 동일 쿼리의 결과를 다시 사용합니다. 캐시 처리된 결과의 사용은 반복되는 쿼리에 한해 유용합니다. 새 쿼리의 경우 캐시 처리된 결과 사용 옵션이 기본적으로 사용 설정되어 있으나 효과는 없습니다.

캐시 처리된 결과 사용 옵션을 사용 중지한 상태에서 쿼리를 반복하면 캐시 처리된 기존 결과를 덮어씁니다. 이 경우 BigQuery에서 쿼리 결과를 계산해야 하며 쿼리 요금이 부과됩니다. 이는 벤치마킹 시나리오에 특히 유용합니다.

캐시 처리된 결과의 검색을 사용 중지하고 쿼리 작업의 실시간 평가를 강제 적용하려면 쿼리 작업의 configuration.query.useQueryCache 속성을 false로 설정하면 됩니다.

캐시 처리된 결과 사용 옵션을 사용 중지하는 방법:

Console

  1. Cloud Console을 엽니다.
    Cloud Console로 이동

  2. 새 쿼리 작성을 클릭합니다.

  3. 쿼리 편집기 텍스트 영역에 유효한 SQL 쿼리를 입력합니다.

  4. 더보기를 클릭하고 쿼리 설정을 선택합니다.

    쿼리 설정

  5. 캐시 환경설정에서 캐시 처리된 결과 사용을 선택 해제합니다.

    캐시 처리된 결과 옵션

기본 UI

  1. 기본 BigQuery 웹 UI로 이동합니다.
    BigQuery 웹 UI로 이동

  2. 쿼리 작성 버튼을 클릭합니다.

  3. 새 쿼리 텍스트 영역에 유효한 SQL 쿼리를 입력합니다.

  4. 옵션 표시를 클릭합니다.

  5. 캐시 처리된 결과 사용을 선택 해제합니다.

캐시 처리된 결과 옵션

CLI

nouse_cache 플래그를 사용하여 쿼리 캐시를 덮어씁니다. 다음 예시에서는 BigQuery에서 캐시 처리된 기존 결과를 사용하지 않고 쿼리를 강제로 처리합니다.

 bq query \
 --nouse_cache \
 --batch \
 'SELECT
    name,
    count
  FROM
    `my-project`.mydataset.names_2013
  WHERE
    gender = "M"
  ORDER BY
    count DESC
  LIMIT
    6'

API

기존 캐시 처리된 결과를 사용하지 않고 쿼리를 처리하려면 query 작업 구성에서 useQueryCache 속성을 false로 설정합니다.

Go

이 샘플을 시도하기 전에 BigQuery 빠른 시작: 클라이언트 라이브러리 사용의 Go 설정 안내를 따르세요. 자세한 내용은 BigQuery Go API 참조 문서를 확인하세요.

import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/bigquery"
	"google.golang.org/api/iterator"
)

// queryDisableCache demonstrates issuing a query and requesting that the query cache is bypassed.
func queryDisableCache(w io.Writer, projectID string) error {
	// projectID := "my-project-id"
	ctx := context.Background()
	client, err := bigquery.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("bigquery.NewClient: %v", err)
	}

	q := client.Query(
		"SELECT corpus FROM `bigquery-public-data.samples.shakespeare` GROUP BY corpus;")
	q.DisableQueryCache = true
	// Location must match that of the dataset(s) referenced in the query.
	q.Location = "US"

	// Run the query and print results when the query job is completed.
	job, err := q.Run(ctx)
	if err != nil {
		return err
	}
	status, err := job.Wait(ctx)
	if err != nil {
		return err
	}
	if err := status.Err(); err != nil {
		return err
	}
	it, err := job.Read(ctx)
	for {
		var row []bigquery.Value
		err := it.Next(&row)
		if err == iterator.Done {
			break
		}
		if err != nil {
			return err
		}
		fmt.Fprintln(w, row)
	}
	return nil
}

자바

기존 캐시 처리된 결과를 사용하지 않고 쿼리를 처리하려면 QueryJobConfiguration을 만들 때 쿼리 캐시 사용false로 설정합니다.

// BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();
String query = "SELECT corpus FROM `bigquery-public-data.samples.shakespeare` GROUP BY corpus;";
QueryJobConfiguration queryConfig =
    QueryJobConfiguration.newBuilder(query)
        // Disable the query cache to force live query evaluation.
        .setUseQueryCache(false)
        .build();

// Print the results.
for (FieldValueList row : bigquery.query(queryConfig).iterateAll()) {
  for (FieldValue val : row) {
    System.out.printf("%s,", val.toString());
  }
  System.out.printf("\n");
}

Node.js

이 샘플을 시도하기 전에 BigQuery 빠른 시작: 클라이언트 라이브러리 사용의 Node.js 설정 안내를 따르세요. 자세한 내용은 BigQuery Node.js API 참조 문서를 확인하세요.

// Import the Google Cloud client library
const {BigQuery} = require('@google-cloud/bigquery');

async function queryDisableCache() {
  // Queries the Shakespeare dataset with the cache disabled.

  // Create a client
  const bigquery = new BigQuery();

  const query = `SELECT corpus
    FROM \`bigquery-public-data.samples.shakespeare\`
    GROUP BY corpus`;
  const options = {
    query: query,
    // Location must match that of the dataset(s) referenced in the query.
    location: 'US',
    useQueryCache: false,
  };

  // Run the query as a job
  const [job] = await bigquery.createQueryJob(options);
  console.log(`Job ${job.id} started.`);

  // Wait for the query to finish
  const [rows] = await job.getQueryResults();

  // Print the results
  console.log('Rows:');
  rows.forEach(row => console.log(row));
}

Python

이 샘플을 시도하기 전에 BigQuery 빠른 시작: 클라이언트 라이브러리 사용의 Python 설정 안내를 따르세요. 자세한 내용은 BigQuery Python API 참조 문서를 확인하세요.

from google.cloud import bigquery

# TODO(developer): Construct a BigQuery client object.
# client = bigquery.Client()

job_config = bigquery.QueryJobConfig(use_query_cache=False)
sql = """
    SELECT corpus
    FROM `bigquery-public-data.samples.shakespeare`
    GROUP BY corpus;
"""
query_job = client.query(sql, job_config=job_config)  # Make an API request.

for row in query_job:
    print(row)

캐시 사용 보장

jobs.insert 함수를 사용하여 쿼리를 실행하는 경우, copy 작업 구성의 createDisposition 속성을 CREATE_NEVER로 설정하여, 캐시 처리된 결과를 사용할 수 없으면 쿼리 작업이 강제로 실패하도록 할 수 있습니다.

쿼리 결과가 캐시에 없으면 NOT_FOUND 오류가 반환됩니다.

캐시 사용 확인

BigQuery에서 캐시를 사용해 결과를 반환했는지 확인하는 방법에는 2가지가 있습니다.

  • Cloud Console 또는 기본 BigQuery 웹 UI를 사용하는 경우, 결과 문자열에 처리된 바이트 수에 대한 정보가 포함되지 않으며 '캐시 처리'라는 단어가 표시됩니다.

    UI의 캐시 표시기

  • BigQuery API를 사용하는 경우에는 쿼리 결과의 cacheHit 속성이 true로 설정됩니다.