스토리지 및 쿼리 비용 예측

BigQuery에서 주문형 쿼리는 읽는 바이트 수를 기준으로 요금이 청구됩니다. 현재 주문형 쿼리 가격 책정은 가격 책정 페이지를 참조하세요.

쿼리를 실행하기 전에 예상 비용을 알아보려면 다음 방법 중 하나를 사용하면 됩니다.

  • 콘솔의 쿼리 검사기
  • bq 명령줄 도구의 --dry_run 플래그
  • API를 사용해 쿼리 작업을 제출할 때 dryRun 매개변수
  • Google Cloud 가격 계산기
  • 클라이언트 라이브러리

이러한 방법으로 제공되는 예상 비용은 여러 요인으로 인해 실제 비용과 다를 수 있습니다. 예를 들어 다음 시나리오를 가정해 보겠습니다.

  • WHERE 절과 같이 데이터를 필터링하는 쿼리 절은 읽는 바이트 수를 크게 줄일 수 있습니다.
  • 추정치가 제공된 후에 추가되거나 삭제된 데이터는 쿼리가 실행될 때 읽는 바이트 수를 늘리거나 줄일 수 있습니다.

쿼리 비용 추정

쿼리 비용을 추정하는 방법:

Console

콘솔에 쿼리를 입력하면 쿼리 검사기가 쿼리 구문을 확인하고 읽을 바이트 수를 추정합니다. 이 추정값을 사용하여 가격 계산기에서 쿼리 비용을 계산할 수 있습니다.

쿼리 검사기

bq

bq 명령줄 도구에서 쿼리를 실행할 때 --dry_run 플래그를 사용하여 읽을 바이트 수를 추정할 수 있습니다. 이 추정값을 사용하여 가격 계산기에서 쿼리 비용을 계산할 수 있습니다.

--dry_run 플래그를 사용하는 bq 도구 쿼리는 다음과 같습니다.

bq query \
--use_legacy_sql=false \
--dry_run \
'SELECT
  column1,
  column2,
  column3
FROM
  `project_id.dataset.table`
LIMIT
  1000'

명령어를 실행하면 응답은 읽을 바이트의 추정값이 응답에 포함됩니다. Query successfully validated. Assuming the tables are not modified, running this query will process 10918 bytes of data.

API

API를 사용하여 연습 실행을 수행하려면 dryRuntrue로 설정하여 쿼리 작업을 제출합니다.

go

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

import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/bigquery"
)

// queryDryRun demonstrates issuing a dry run query to validate query structure and
// provide an estimate of the bytes scanned.
func queryDryRun(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)
	}
	defer client.Close()

	q := client.Query(`
	SELECT
		name,
		COUNT(*) as name_count
	FROM ` + "`bigquery-public-data.usa_names.usa_1910_2013`" + `
	WHERE state = 'WA'
	GROUP BY name`)
	q.DryRun = true
	// Location must match that of the dataset(s) referenced in the query.
	q.Location = "US"

	job, err := q.Run(ctx)
	if err != nil {
		return err
	}
	// Dry run is not asynchronous, so get the latest status and statistics.
	status := job.LastStatus()
	if err != nil {
		return err
	}
	fmt.Fprintf(w, "This query will process %d bytes\n", status.Statistics.TotalBytesProcessed)
	return nil
}

자바

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

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.Job;
import com.google.cloud.bigquery.JobInfo;
import com.google.cloud.bigquery.JobStatistics;
import com.google.cloud.bigquery.QueryJobConfiguration;

// Sample to run dry query on the table
public class QueryDryRun {

  public static void runQueryDryRun() {
    String query =
        "SELECT name, COUNT(*) as name_count "
            + "FROM `bigquery-public-data.usa_names.usa_1910_2013` "
            + "WHERE state = 'WA' "
            + "GROUP BY name";
    queryDryRun(query);
  }

  public static void queryDryRun(String query) {
    try {
      // Initialize client that will be used to send requests. This client only needs to be created
      // once, and can be reused for multiple requests.
      BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

      QueryJobConfiguration queryConfig =
          QueryJobConfiguration.newBuilder(query).setDryRun(true).setUseQueryCache(false).build();

      Job job = bigquery.create(JobInfo.of(queryConfig));
      JobStatistics.QueryStatistics statistics = job.getStatistics();

      System.out.println(
          "Query dry run performed successfully." + statistics.getTotalBytesProcessed());
    } catch (BigQueryException e) {
      System.out.println("Query not performed \n" + e.toString());
    }
  }
}

Node.js

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

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

async function queryDryRun() {
  // Runs a dry query of the U.S. given names dataset for the state of Texas.

  const query = `SELECT name
    FROM \`bigquery-public-data.usa_names.usa_1910_2013\`
    WHERE state = 'TX'
    LIMIT 100`;

  // For all options, see https://cloud.google.com/bigquery/docs/reference/rest/v2/jobs/query
  const options = {
    query: query,
    // Location must match that of the dataset(s) referenced in the query.
    location: 'US',
    dryRun: true,
  };

  // Run the query as a job
  const [job] = await bigquery.createQueryJob(options);

  // Print the status and statistics
  console.log('Status:');
  console.log(job.metadata.status);
  console.log('\nJob Statistics:');
  console.log(job.metadata.statistics);
}

PHP

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

use Google\Cloud\BigQuery\BigQueryClient;

/** Uncomment and populate these variables in your code */
// $projectId = 'The Google project ID';
// $query = 'SELECT id, view_count FROM `bigquery-public-data.stackoverflow.posts_questions`';

// Construct a BigQuery client object.
$bigQuery = new BigQueryClient([
    'projectId' => $projectId,
]);

// Set job configs
$jobConfig = $bigQuery->query($query);
$jobConfig->useQueryCache(false);
$jobConfig->dryRun(true);

// Extract query results
$queryJob = $bigQuery->startJob($jobConfig);
$info = $queryJob->info();

printf('This query will process %s bytes' . PHP_EOL, $info['statistics']['totalBytesProcessed']);

Python

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

Python 클라이언트 라이브러리를 사용해 테스트 실행을 수행하려면 QueryJobConfig.dry_run 속성을 True로 설정합니다. 테스트 실행 쿼리 구성을 제공하면 Client.query()는 항상 완료된 QueryJob을 반환합니다.
from google.cloud import bigquery

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

job_config = bigquery.QueryJobConfig(dry_run=True, use_query_cache=False)

# Start the query, passing in the extra configuration.
query_job = client.query(
    (
        "SELECT name, COUNT(*) as name_count "
        "FROM `bigquery-public-data.usa_names.usa_1910_2013` "
        "WHERE state = 'WA' "
        "GROUP BY name"
    ),
    job_config=job_config,
)  # Make an API request.

# A dry run query completes immediately.
print("This query will process {} bytes.".format(query_job.total_bytes_processed))

Google Cloud 가격 계산기를 사용하여 쿼리 비용 추정

Google Cloud 가격 계산기로 주문형 쿼리 비용을 추정하려면 쿼리에서 처리하는 바이트 수를 B, KB, MB, GB, TB, PB 단위로 입력합니다. 쿼리에서 1TB 미만을 처리하는 경우 BigQuery에서는 매달 1TB까지는 주문형 쿼리 처리를 무료로 지원하므로 추정값이 $0입니다.

가격 계산기

가격 계산기를 사용해 쿼리 비용을 추정하는 방법:

  1. Google Cloud 가격 계산기를 열고
  2. BigQuery를 클릭합니다.
  3. 주문형 탭을 클릭합니다.
  4. 테이블 이름에 테이블 이름을 입력합니다. 예를 들면 airports입니다.
  5. 스토리지 가격 책정스토리지 필드에 0을 입력합니다.
  6. 쿼리 가격 책정에 연습 실행 또는 쿼리 검사기로 얻은 읽은 바이트 수 추정값을 입력합니다. 가격 계산기
  7. 추정값에 추가를 클릭합니다.
  8. 추정값이 오른쪽에 나타납니다. 추정값을 저장하거나 이메일로 보낼 수 있습니다. 주문형 계산기

이 경우에는 쿼리에서 읽은 바이트 수가 무료 등급을 통해 제공되는 주문형 처리 1TB에 미치지 못합니다. 따라서 예상 비용은 $0입니다.

가격 계산기에 정액제 가격 포함

결제 계정에 정액제 가격 책정을 적용한 경우 정액제 탭을 클릭하고 정액제를 선택한 후 스토리지 비용을 추정값에 추가할 수 있습니다.

정액제 계산기

자세한 내용은 정액제를 참조하세요.

Google Cloud 가격 계산기를 사용하여 스토리지 비용 추정

Google Cloud 가격 계산기로 스토리지 비용을 추정하려면 바이트 수를 B, KB, MB, GB, TB, PB 단위로 입력합니다. BigQuery는 월 10GB의 스토리지를 무료로 제공합니다.

가격 계산기를 사용해 저장소 비용을 추정하는 방법:

  1. Google Cloud 가격 계산기를 엽니다.
  2. BigQuery를 클릭합니다.
  3. 주문형 탭을 클릭합니다.
  4. 테이블 이름에 테이블 이름을 입력합니다. 예를 들면 airports입니다.
  5. 스토리지 가격 책정스토리지 필드에 100를 입력합니다. 측정 단위는 GB로 설정된 채로 둡니다.
  6. 추정값에 추가를 클릭합니다.
  7. 추정값이 오른쪽에 나타납니다. 추정값을 저장하거나 이메일로 보낼 수 있습니다. 가격 계산기

쿼리 크기 계산

이 섹션에서는 주문형 결제 모델을 사용하여 다양한 유형의 쿼리에서 처리되는 바이트 수를 계산하는 방법을 설명합니다.

DML 문

주문형 결제를 사용하는 경우 BigQuery는 문에서 처리된 바이트 수를 기준으로 데이터 조작 언어(DML) 문에 요금을 부과합니다.

파티션을 나누지 않은 테이블

파티션을 나누지 않은 테이블의 경우 처리된 바이트 수는 다음과 같이 계산됩니다.

  • q = 쿼리로 스캔한 테이블에서 참조한 열에 대해 처리한 바이트의 합계입니다.
  • t = 쿼리에서 해당 열의 참조 또는 수정 여부와 상관없이 쿼리가 시작될 때 업데이트된 테이블의 모든 열에 대한 바이트의 합계입니다.
DML 문 처리한 바이트
INSERT q
UPDATE q + t
DELETE q + t
MERGE INSERT 절만 있는 경우: q
UPDATE 또는 DELETE 절이 있는 경우: q + t

파티션을 나눈 테이블

파티션을 나눈 테이블의 경우 처리된 바이트 수는 다음과 같이 계산됩니다.

  • q' = 쿼리로 스캔한 모든 파티션에서 참조한 열에 대해 처리한 바이트의 합계입니다.
  • t = 쿼리에서 해당 열의 참조 또는 수정 여부와 상관없이 쿼리가 시작될 때 업데이트된 열의 업데이트 또는 스캐닝된 파티션의 모든 열에 대한 바이트의 합계입니다.
DML 문 처리한 바이트
INSERT q'
UPDATE q' + t'
DELETE q' + t'
MERGE MERGE 문에 INSERT 절만 있는 경우: q'
MERGE 문에 UPDATE 또는 DELETE 절이 있는 경우: q' + t'

DDL 문

주문형 결제를 사용하는 경우 BigQuery는 쿼리에서 처리한 바이트 수에 따라 데이터 정의 언어(DDL) 쿼리에 요금을 부과합니다.

DDL 문 처리한 바이트
CREATE TABLE 없음
CREATE TABLE ... AS SELECT ... 쿼리로 스캔한 테이블에서 참조한 모든 열에 대해 처리한 바이트의 합계입니다.
CREATE VIEW 없음
DROP TABLE 없음
DROP VIEW 없음

멀티 문 쿼리

주문형 결제를 이용하는 경우 BigQuery는 멀티 문 쿼리를 실행하는 동안 처리된 바이트 수를 기준으로 멀티 문 쿼리에 요금을 부과합니다.

이러한 멀티 문 쿼리에는 다음 가격이 적용됩니다.

  • DECLARE: DEFAULT 표현식에서 참조한 모든 테이블에서 스캔한 바이트의 합계에 대해 요금이 부과됩니다. 테이블 참조가 없는 DECLARE 문은 비용이 발생하지 않습니다.
  • SET: 표현식에서 참조한 모든 테이블에서 스캔한 바이트의 합계에 대해 요금이 부과됩니다. 테이블 참조가 없는 SET 문은 비용이 발생하지 않습니다.
  • IF: 조건 표현식에서 참조한 모든 테이블에서 스캔한 바이트의 합계에 대해 요금이 부과됩니다. 테이블 참조가 없는 IF 조건 표현식은 비용이 발생하지 않습니다. 실행되지 않은 IF 블록의 문에 대해서도 비용이 발생하지 않습니다.
  • WHILE: 조건 표현식에서 참조한 모든 테이블에서 스캔한 바이트의 합계에 대해 요금이 부과됩니다. 조건 표현식에서 테이블 참조가 없는 WHILE 문은 비용이 발생하지 않습니다. 실행되지 않은 WHILE 블록의 문에 대해서도 비용이 발생하지 않습니다.
  • CONTINUE 또는 ITERATE: 관련 비용이 없습니다.
  • BREAK 또는 LEAVE: 관련 비용이 없습니다.
  • BEGIN 또는 END: 관련 비용이 없습니다.

임시 테이블의 경우 멀티 문 쿼리가 실행되는 동안에는 스토리지 요금이 부과되지 않습니다. 하지만 임시 테이블을 생성, 수정 또는 쿼리하는 모든 문에 대해서는 정상적으로 요금이 부과됩니다.

멀티 문 쿼리가 실패할 경우 실패 전까지 발생한 모든 문 비용이 적용됩니다. 실패한 문에 대해서는 비용이 발생하지 않습니다.

멀티 문 쿼리 가격 책정 예시

다음 예시에는 다음 문에서 발생하는 비용(있는 경우)을 설명하는 주석이 모든 문 앞에 포함되어 있습니다.

-- No cost, since no tables are referenced.
DECLARE x DATE DEFAULT CURRENT_DATE();
-- Incurs the cost of scanning string_col from dataset.table.
DECLARE y STRING DEFAULT (SELECT MAX(string_col) FROM dataset.table);
-- Incurs the cost of copying the data from dataset.big_table.  Once the
-- table is created, you are not charged for storage while the rest of the
-- multi-statement query runs.
CREATE TEMP TABLE t AS SELECT * FROM dataset.big_table;
-- Incurs the cost of scanning column1 from temporary table t.
SELECT column1 FROM t;
-- No cost, since y = 'foo' doesn't reference a table.
IF y = 'foo' THEN
  -- Incurs the cost of scanning all columns from dataset.other_table, if
  -- y was equal to 'foo', or otherwise no cost since it is not executed.
  SELECT * FROM dataset.other_table;
ELSE
  -- Incurs the cost of scanning all columns from dataset.different_table, if
  -- y was not equal to 'foo', or otherwise no cost since it is not executed.
  UPDATE dataset.different_table
  SET col = 10
  WHERE true;
END IF;
-- Incurs the cost of scanning date_col from dataset.table for each
-- iteration of the loop.
WHILE x < (SELECT MIN(date_col) FROM dataset.table) DO
  -- No cost, since the expression does not reference any tables.
  SET x = DATE_ADD(x, INTERVAL 1 DAY);
  -- No cost, since the expression does not reference any tables.
  IF true THEN
    -- LEAVE has no associated cost.
    LEAVE;
  END IF;
  -- Never executed, since the IF branch is always taken, so does not incur
  -- a cost.
  SELECT * FROM dataset.big_table;
END WHILE;

클러스터링된 테이블

클러스터링된 테이블을 사용하면 데이터를 프루닝해 쿼리로 데이터가 처리되지 않도록 하여 쿼리 비용을 절감할 수 있습니다. 이 프로세스를 블록 프루닝이라고 합니다.

블록 프루닝

BigQuery는 클러스터링 열의 값에 따라 클러스터링된 테이블의 데이터를 정렬하고 블록으로 정리합니다.

클러스터링된 열의 필터를 포함한 쿼리를 클러스터링된 테이블에 실행하는 경우 BigQuery는 필터 표현식과 블록 메타데이터를 사용해 쿼리로 스캔할 블록을 프루닝합니다. 이렇게 하면 BigQuery가 관련 블록만 스캔할 수 있습니다.

블록이 프루닝되면 스캔되지 않습니다. 스캔된 블록만이 쿼리로 처리된 데이터의 바이트를 계산하는 데 사용됩니다. 클러스터링된 테이블에 대한 쿼리로 처리되는 바이트 수는 스캔된 블록에서 쿼리에 참조된 각 열에서 읽은 바이트 수의 합계와 동일합니다.

클러스터링된 테이블이 여러 필터를 사용하는 쿼리에서 여러 번 참조되는 경우, BigQuery는 필터마다 적절한 블록의 열 스캔 작업에 대해 요금을 청구합니다.

클러스터링된 테이블 가격 책정 예시

이름이 ClusteredSalesData인 클러스터링된 테이블이 있습니다. 이 테이블은 timestamp 열로 파티션을 나누고 customer_id 열로 클러스터링됩니다. 데이터는 다음 블록 세트로 정리됩니다.

파티션 식별자 블록 ID 블록의 customer_id 최솟값 블록의 customer_id 최댓값
20160501 B1 10000 19999
20160501 B2 20000 24999
20160502 B3 15000 17999
20160501 B4 22000 27999

다음 쿼리를 테이블에 실행합니다. 쿼리에는 customer_id 열에 필터가 포함되어 있습니다.

SELECT
  SUM(totalSale)
FROM
  `mydataset.ClusteredSalesData`
WHERE
  customer_id BETWEEN 20000
  AND 23000
  AND DATE(timestamp) = "2016-05-01"

이 쿼리는 다음과 같은 작업을 합니다.

  • 블록 B2와 B4에서 timestamp, customer_id, totalSale 열을 스캔합니다.
  • timestamp 파티션을 나눈 열의 DATE(timestamp) = "2016-05-01" 필터 조건자로 인해 B3 블록을 프루닝합니다.
  • customer_id 클러스터링 열의 customer_id BETWEEN 20000 AND 23000 필터 조건자로 인해 B1 블록을 프루닝합니다.

Cloud Storage에서 열 형식 쿼리

외부 데이터가 ORC 또는 Parquet 형식으로 저장되어 있는 경우 청구되는 바이트 수는 BigQuery에서 읽는 열로 제한됩니다. 외부 데이터 소스의 데이터 유형은 쿼리에 의해 BigQuery 데이터 유형으로 변환되므로 읽은 바이트 수는 BigQuery 데이터 유형의 크기에 따라 계산됩니다. 데이터 유형 변환에 대한 자세한 내용은 다음 페이지를 참조하세요.