JOBS 뷰

INFORMATION_SCHEMA.JOBS 뷰에는 현재 프로젝트의 모든 BigQuery 작업에 대한 거의 실시간의 메타데이터가 포함되어 있습니다.

필요한 역할

INFORMATION_SCHEMA.JOBS 뷰를 쿼리하는 데 필요한 권한을 얻으려면 관리자에게 프로젝트에 대한 BigQuery 리소스 뷰어 (roles/bigquery.resourceViewer) IAM 역할을 부여해 달라고 요청하세요. 역할 부여에 대한 자세한 내용은 프로젝트, 폴더, 조직에 대한 액세스 관리를 참조하세요.

이 사전 정의된 역할에는 INFORMATION_SCHEMA.JOBS 뷰를 쿼리하는 데 필요한 bigquery.jobs.listAll 권한이 포함되어 있습니다.

커스텀 역할이나 다른 사전 정의된 역할을 사용하여 이 권한을 부여받을 수도 있습니다.

BigQuery 권한에 대한 자세한 내용은 IAM으로 액세스 제어를 참조하세요.

스키마

기본 데이터는 creation_time 열로 파티션을 나누고 project_iduser_email로 클러스터링됩니다. query_info 열에는 쿼리 작업에 대한 추가 정보가 포함됩니다.

INFORMATION_SCHEMA.JOBS 뷰에는 다음과 같은 스키마가 있습니다.

열 이름 데이터 유형
bi_engine_statistics RECORD 프로젝트가 BI Engine을 사용하도록 구성된 경우 이 필드에는 BiEngineStatistics가 포함됩니다. 그 외의 경우에는 NULL입니다.
cache_hit BOOLEAN 이 작업의 쿼리 결과가 캐시에서 제공되었는지 여부 멀티 쿼리 문 작업이 있는 경우 상위 쿼리의 cache_hitNULL입니다.
creation_time TIMESTAMP (파티션 나누기 열) 이 작업의 생성 시간입니다. 파티션 나누기는 이 타임스탬프의 UTC 시간을 기반으로 합니다.
destination_table RECORD 결과에 대한 대상 테이블입니다(해당하는 경우).
end_time TIMESTAMP 작업의 종료 시간입니다(에포크 이후의 경과 시간(밀리초)). 이 필드는 작업이 DONE 상태가 되는 시간을 나타냅니다.
error_result RECORD ErrorProto 객체로서의 오류 세부정보입니다.
job_creation_reason.code STRING 작업이 생성된 대략적인 이유를 지정합니다.
가능한 값은 다음과 같습니다.
  • REQUESTED: 작업 생성이 요청되었습니다.
  • LONG_RUNNING: 쿼리 요청이 QueryRequest의 timeoutMs 필드로 지정된 시스템 정의 제한 시간을 초과하여 실행되었습니다. 따라서 작업이 생성된 장기 실행 작업으로 간주되었습니다.
  • LARGE_RESULTS: 쿼리의 결과가 인라인 응답에 맞지 않습니다.
  • OTHER: 시스템에서 쿼리를 작업으로 실행해야 한다고 판단했습니다.
job_id STRING 작업이 생성된 경우 작업의 ID입니다. 그렇지 않으면 짧은 쿼리 모드를 사용하는 쿼리의 쿼리 ID입니다. 예를 들면 bquxjob_1234입니다.
job_stages RECORD 작업의 쿼리 단계입니다.

참고: 행 수준 액세스 정책이 적용되는 테이블에서 읽는 쿼리의 경우 이 열의 값이 비어 있습니다. 자세한 내용은 BigQuery의 행 수준 보안 권장사항을 참조하세요.

job_type STRING 작업의 유형. QUERY, LOAD, EXTRACT, COPY, NULL일 수 있습니다. NULL 값은 스크립트 작업 문 평가와 같은 내부 작업을 나타냅니다.
labels RECORD 키-값 쌍으로 작업에 적용된 라벨의 배열
parent_job_id STRING 상위 작업의 ID(있는 경우)
priority STRING 이 작업의 우선순위. 유효한 값은 INTERACTIVEBATCH입니다.
project_id STRING (클러스터링 열) 프로젝트의 ID입니다.
project_number INTEGER 프로젝트의 번호입니다.
query STRING SQL 쿼리 텍스트. JOBS_BY_PROJECT 뷰에만 쿼리 열이 있습니다.
referenced_tables RECORD 작업에서 참조하는 테이블의 배열입니다. 캐시 적중이 아닌 쿼리 작업만 채워집니다.
reservation_id STRING 이 작업에 할당된 기본 예약의 이름이며 RESERVATION_ADMIN_PROJECT:RESERVATION_LOCATION.RESERVATION_NAME 형식입니다.
이 출력에서 각 항목의 의미는 다음과 같습니다.
  • RESERVATION_ADMIN_PROJECT: 예약을 관리하는 Google Cloud 프로젝트의 이름입니다.
  • RESERVATION_LOCATION: 예약 위치입니다.
  • RESERVATION_NAME: 예약 이름입니다.
edition STRING 이 작업에 할당된 예약과 연결된 버전입니다. 버전에 대한 자세한 내용은 BigQuery 버전 소개를 참조하세요.
session_info RECORD 이 작업이 실행된 세션에 대한 세부정보입니다(있는 경우).
start_time TIMESTAMP 작업의 시작 시간입니다(에포크 이후의 경과 시간(밀리초)). 이 필드는 작업이 PENDING 상태에서 RUNNING 또는 DONE 상태가 되는 시간을 나타냅니다.
state STRING 작업의 실행 상태. 유효한 상태에는 PENDING, RUNNING, DONE이 있습니다.
statement_type STRING 쿼리 문의 유형입니다. 예를 들면 DELETE, INSERT, SCRIPT, SELECT, UPDATE입니다. 유효한 값 목록은 QueryStatementType을 참조하세요.
timeline RECORD 작업의 쿼리 타임라인입니다. 쿼리 실행 스냅샷을 포함합니다.
total_bytes_billed INTEGER 프로젝트가 주문형 가격 책정을 사용하도록 구성된 경우 이 필드에는 작업에 대해 청구되는 총 바이트가 포함됩니다. 프로젝트가 정액제를 사용하도록 구성된 경우 바이트 요금이 청구되지 않으며 이 필드는 참고용이 됩니다.

참고: 행 수준 액세스 정책이 적용되는 테이블에서 읽는 쿼리의 경우 이 열의 값이 비어 있습니다. 자세한 내용은 BigQuery의 행 수준 보안 권장사항을 참조하세요.

total_bytes_processed INTEGER

작업에서 처리한 총 바이트

참고: 행 수준 액세스 정책이 적용되는 테이블에서 읽는 쿼리의 경우 이 열의 값이 비어 있습니다. 자세한 내용은 BigQuery의 행 수준 보안 권장사항을 참조하세요.

total_modified_partitions INTEGER 작업에서 수정한 총 파티션 수입니다. 이 필드는 LOADQUERY 작업에 채워집니다.
total_slot_ms INTEGER 재시도를 포함하여 RUNNING 상태의 전체 기간 동안 작업의 슬롯 밀리초입니다.
transaction_id STRING 이 작업이 실행된 트랜잭션의 ID입니다(있는 경우). (미리보기)
user_email STRING (클러스터링 열) 작업을 실행한 사용자의 이메일 주소 또는 서비스 계정입니다.
query_info.resource_warning STRING 쿼리 처리 중 리소스 사용이 시스템의 내부 기준점을 초과할 경우 표시되는 경고 메시지입니다.
성공적인 쿼리 작업에는 resource_warning 필드가 채워질 수 있습니다. resource_warning의 경우 쿼리를 최적화하고 query_hashes를 사용하여 동일한 쿼리 집합의 성능 추세를 모니터링을 설정하기 위한 추가 데이터 포인트가 제공됩니다.
query_info.query_hashes.normalized_literals STRING 쿼리의 해시를 포함합니다. normalized_literals는 주석, 매개변수 값, UDF, 리터럴을 무시하는 16진수 STRING 해시입니다. 기본 뷰가 변경되거나 쿼리가 SELECT *와 같은 열을 암시적으로 참조하고 테이블 스키마가 변경되면 해시 값이 달라집니다.
이 필드는 캐시 적중이 아닌 성공한 GoogleSQL 쿼리에 표시됩니다.
query_info.performance_insights RECORD 작업에 대한 성능 통계.
query_info.optimization_details STRUCT 작업의 기록 기반 최적화.
transferred_bytes INTEGER BigQuery Omni 교차 클라우드 전송 작업과 같은 교차 클라우드 쿼리를 위해 전송된 총 바이트 수입니다.
materialized_view_statistics RECORD 쿼리 작업에서 고려되는 구체화된 뷰 통계입니다. (미리보기)
metadata_cache_statistics RECORD 쿼리 작업에서 참조된 테이블의 메타데이터 열 색인 사용 통계입니다.
search_statistics RECORD 검색어 통계 (미리보기)
query_dialect STRING 이 필드는 2025년 5월부터 사용할 수 있습니다. 작업에 사용된 쿼리 언어입니다. 유효한 값은
입니다.
  • GOOGLE_SQL: 작업에 GoogleSQL 사용이 요청되었습니다.
  • LEGACY_SQL: 작업에 LegacySQL을 사용하도록 요청되었습니다.
  • DEFAULT_LEGACY_SQL: 작업 요청에 지정된 쿼리 방언이 없습니다. BigQuery는 LegacySQL의 기본값을 사용했습니다.
  • DEFAULT_GOOGLE_SQL: 작업 요청에 지정된 쿼리 방언이 없습니다. BigQuery는 GoogleSQL의 기본값을 사용했습니다.

이 필드는 쿼리 작업에만 채워집니다. 쿼리 방언의 기본 선택은 구성 설정으로 제어할 수 있습니다.

쿼리 작업의 요약 비용을 찾기 위해 INFORMATION_SCHEMA.JOBS를 쿼리할 때는 SCRIPT 문 유형을 제외합니다. 그렇지 않으면 일부 값이 두 번 계산됩니다. SCRIPT 행에는 이 작업의 일부로 실행된 모든 하위 작업의 요약 값이 포함됩니다.

멀티 문 쿼리 작업

멀티 문 쿼리 작업은 절차적 언어를 사용하는 쿼리 작업입니다. 멀티 문 쿼리 작업은 DECLARE로 변수를 정의하거나 IF 또는 WHILE과 같은 흐름 제어 문을 포함하는 경우가 많습니다. INFORMATION_SCHEMA.JOBS를 쿼리할 때는 멀티 문 쿼리 작업과 다른 작업의 차이를 인식해야 합니다. 멀티 문 쿼리 작업의 특성은 다음과 같습니다.

  • statement_type = SCRIPT
  • reservation_id = NULL

하위 작업.

각 멀티 문 쿼리 작업의 하위 작업에는 멀티 문 쿼리 작업 자체를 가리키는 parent_job_id가 있습니다. 여기에는 이 작업의 일부로 실행된 모든 하위 작업에 대한 요약 값이 포함됩니다.

이러한 이유로 쿼리 작업의 요약 비용을 찾기 위해 INFORMATION_SCHEMA.JOBS를 쿼리할 때는 SCRIPT 문 유형을 제외해야 합니다. 그렇지 않으면 total_slot_ms와 같은 일부 값은 두 번 계산될 수 있습니다.

데이터 보관

이 뷰에는 현재 실행 중인 작업과 지난 180일 동안의 작업 기록이 포함되어 있습니다.

범위 및 구문

이 뷰에 대한 쿼리에는 리전 한정자가 있어야 합니다. 다음 표에는 이 뷰의 리전 범위가 나와 있습니다.

뷰 이름 리소스 범위 리전 범위
[PROJECT_ID.]`region-REGION`.INFORMATION_SCHEMA.JOBS[_BY_PROJECT] 프로젝트 수준 REGION
다음을 바꿉니다.
  • 선택사항: PROJECT_ID: Google Cloud 프로젝트의 ID입니다. 지정하지 않으면 기본 프로젝트가 사용됩니다.
  • REGION: 모든 데이터 세트 리전 이름입니다. 예를 들면 `region-us`입니다.

예시

기본 프로젝트가 아닌 프로젝트에 대해 쿼리를 실행하려면 다음 형식으로 프로젝트 ID를 추가합니다.

`PROJECT_ID`.`region-REGION_NAME`.INFORMATION_SCHEMA.JOBS
다음을 바꿉니다.

  • PROJECT_ID: 프로젝트 ID
  • REGION_NAME: 프로젝트 리전

예를 들면 `myproject`.`region-us-central1`.INFORMATION_SCHEMA.JOBS입니다.

주문형 작업 사용량과 결제 데이터 비교

주문형 가격 책정을 사용하는 프로젝트의 경우 INFORMATION_SCHEMA.JOBS 뷰를 사용하여 지정된 기간의 컴퓨팅 요금을 검토할 수 있습니다.

용량 기반(슬롯) 가격 책정을 사용하는 프로젝트의 경우 INFORMATION_SCHEMA.RESERVATIONS_TIMELINE을 사용하여 지정된 기간 동안의 컴퓨팅 요금을 검토할 수 있습니다.

다음 쿼리는 청구된 TiB와 그에 따른 요금의 일일 예상 집계를 생성합니다. 제한사항 섹션에서는 이러한 예상 비용이 청구서와 일치하지 않을 수 있는 경우를 설명합니다.

이 예시에서는 다음 추가 변수를 설정해야 합니다. 여기에서 사용하기 쉽게 수정할 수 있습니다.

  • START_DATE: 집계할 가장 빠른 날짜입니다(당일 포함).
  • END_DATE: 집계할 최신 날짜입니다(당일 포함).
  • PRICE_PER_TIB: 예상 청구액에 사용되는 TiB당 주문형 가격입니다.
CREATE TEMP FUNCTION isBillable(error_result ANY TYPE)
AS (
  -- You aren't charged for queries that return an error.
  error_result IS NULL
  -- However, canceling a running query might incur charges.
  OR error_result.reason = 'stopped'
);

-- BigQuery hides the number of bytes billed on all queries against tables with
-- row-level security.
CREATE TEMP FUNCTION isMaybeUsingRowLevelSecurity(
  job_type STRING, tib_billed FLOAT64, error_result ANY TYPE)
AS (
  job_type = 'QUERY'
  AND tib_billed IS NULL
  AND isBillable(error_result)
);

WITH
  query_params AS (
    SELECT
      date 'START_DATE' AS start_date,  -- inclusive
      date 'END_DATE' AS end_date,  -- inclusive
  ),
  usage_with_multiplier AS (
    SELECT
      job_type,
      error_result,
      creation_time,
      -- Jobs are billed by end_time in PST8PDT timezone, regardless of where
      -- the job ran.
      EXTRACT(date FROM end_time AT TIME ZONE 'PST8PDT') billing_date,
      total_bytes_billed / 1024 / 1024 / 1024 / 1024 total_tib_billed,
      CASE statement_type
        WHEN 'SCRIPT' THEN 0
        WHEN 'CREATE_MODEL' THEN 50 * PRICE_PER_TIB
        ELSE PRICE_PER_TIB
        END AS multiplier,
    FROM `region-REGION_NAME`.INFORMATION_SCHEMA.JOBS
  )
SELECT
  billing_date,
  sum(total_tib_billed * multiplier) estimated_charge,
  sum(total_tib_billed) estimated_usage_in_tib,
  countif(isMaybeUsingRowLevelSecurity(job_type, total_tib_billed, error_result))
    AS jobs_using_row_level_security,
FROM usage_with_multiplier, query_params
WHERE
  1 = 1
  -- Filter by creation_time for partition pruning.
  AND date(creation_time) BETWEEN date_sub(start_date, INTERVAL 2 day) AND end_date
  AND billing_date BETWEEN start_date AND end_date
  AND isBillable(error_result)
GROUP BY billing_date
ORDER BY billing_date;

제한사항

  • BigQuery는 행 수준 보안을 갖춘 테이블에 대한 쿼리의 일부 통계를 숨깁니다. 제공된 쿼리는 영향을 받는 작업 수를 jobs_using_row_level_security로 계산하지만 청구 가능한 사용량에 액세스할 수 없습니다.

  • BigQuery ML 주문형 쿼리 가격 책정은 생성 중인 모델의 유형에 따라 다릅니다. INFORMATION_SCHEMA.JOBS는 생성된 모델 유형을 추적하지 않으므로 제공된 쿼리는 모든 CREATE_MODEL 문에서 청구 요금이 더 높은 모델 유형을 만들었다고 가정합니다.

  • Apache Spark 절차에는 유사한 가격 책정 모델이 사용되지만 요금은 BigQuery Enterprise 버전 사용한 만큼만 지불하는 SKU로 보고됩니다. INFORMATION_SCHEMA.JOBS는 이 사용량을 total_bytes_billed로 추적하지만 사용량이 나타내는 SKU를 확인할 수 없습니다.

평균 슬롯 사용량 계산

다음 예시에서는 지정된 프로젝트의 지난 7일 동안의 모든 쿼리에 대한 평균 슬롯 사용량을 계산합니다. 이 계산은 일주일 동안 일관된 슬롯 사용량을 가진 프로젝트에서 가장 정확합니다. 프로젝트의 슬롯 사용량이 일정하지 않으면 이 사용량 수치가 예상보다 낮을 수 있습니다.

쿼리를 실행하려면 다음 안내를 따르세요.

SELECT
  SUM(total_slot_ms) / (1000 * 60 * 60 * 24 * 7) AS avg_slots
FROM
  `region-REGION_NAME`.INFORMATION_SCHEMA.JOBS
WHERE
  -- Filter by the partition column first to limit the amount of data scanned.
  -- Eight days allows for jobs created before the 7 day end_time filter.
  creation_time BETWEEN TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 8 DAY) AND CURRENT_TIMESTAMP()
  AND job_type = 'QUERY'
  AND statement_type != 'SCRIPT'
  AND end_time BETWEEN TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY) AND CURRENT_TIMESTAMP();

결과는 다음과 비슷합니다.

+------------+
| avg_slots  |
+------------+
| 3879.1534  |
+------------+

특정 예약에 대한 사용량은 WHERE reservation_id = "…"로 확인할 수 있습니다. 이는 일정 기간 동안 예약 사용 비율을 결정하는 데 유용할 수 있습니다. 스크립트 작업의 경우 상위 작업은 하위 작업의 총 슬롯 사용량도 보고합니다. 중복 계산이 방지되도록 WHERE statement_type != "SCRIPT"를 사용하여 상위 작업을 제외합니다.

개별 작업의 평균 슬롯 사용량을 확인하려면 total_slot_ms / TIMESTAMP_DIFF(end_time, start_time, MILLISECOND)를 사용합니다.

쿼리 우선순위별 최근 활성 쿼리 수

다음 예에서는 지난 7시간 이내에 시작된 쿼리 수를 우선순위(대화형 또는 일괄)별로 그룹화하여 표시합니다.

SELECT
  priority,
  COUNT(*) active_jobs
FROM
  `region-REGION_NAME`.INFORMATION_SCHEMA.JOBS
WHERE
  creation_time > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 hour)
  AND job_type = 'QUERY'
GROUP BY priority;

결과는 다음과 비슷합니다.

+-------------+-------------+
| priority    | active_jobs |
+-------------+-------------+
| INTERACTIVE |           2 |
| BATCH       |           3 |
+-------------+-------------+

priority 필드는 쿼리가 INTERACTIVE인지 BATCH인지를 나타냅니다.

로드 작업 기록 보기

다음 예시에서는 지정된 프로젝트의 일괄 로드 작업을 제출한 모든 사용자 또는 서비스 계정을 나열합니다. 시간 경계가 지정되지 않았으므로 이 쿼리는 사용 가능한 모든 기록을 검사합니다.

SELECT
  user_email AS user,
  COUNT(*) num_jobs
FROM
  `region-REGION_NAME`.INFORMATION_SCHEMA.JOBS
WHERE
  job_type = 'LOAD'
GROUP BY
  user_email;

결과는 다음과 비슷합니다.

+--------------+
| user         |
+--------------+
| abc@xyz.com  |
| xyz@xyz.com  |
| bob@xyz.com  |
+--------------+

로드 작업 수를 가져와 사용된 일일 작업 할당량 확인

다음 예시는 일일 작업 할당량의 사용량을 확인할 수 있도록 날짜, 데이터 세트, 테이블별로 작업 수를 반환합니다.

SELECT
    DATE(creation_time) as day,
    destination_table.project_id as project_id,
    destination_table.dataset_id as dataset_id,
    destination_table.table_id as table_id,
    COUNT(job_id) AS load_job_count
 FROM
   `region-REGION_NAME`.INFORMATION_SCHEMA.JOBS
 WHERE
    creation_time BETWEEN TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 8 DAY) AND CURRENT_TIMESTAMP()
    AND job_type = "LOAD"
GROUP BY
    day,
    project_id,
    dataset_id,
    table_id
ORDER BY
    day DESC;
참고: `INFORMATION_SCHEMA` 뷰 이름은 대소문자를 구분합니다. 결과는 다음과 비슷합니다.
+-------------+------------+-------------+----------+-----------------+
|day          | project_id | dataset_id  | table_id | load_job_count  |
+-------------+------------+-------------+----------+-----------------+
| 2020-10-10  | my_project | dataset1    | orders   | 58              |
| 2020-10-10  | my_project | dataset1    | product  | 20              |
| 2020-10-10  | my_project | dataset1    | sales    | 11              |
+-------------+------------+-------------+----------+-----------------+

최근에 실패한 작업 몇 개 가져오기

다음 예는 최근 실패한 작업 3개를 보여줍니다.

SELECT
   job_id,
  creation_time,
  user_email,
   error_result
 FROM `region-REGION_NAME`.INFORMATION_SCHEMA.JOBS_BY_PROJECT
WHERE
  error_result.reason != "Null"
ORDER BY
  creation_time DESC
LIMIT 3;

결과는 다음과 비슷하게 표시됩니다.

+------------+--------------------------+------------------+-------------------------------------+
| job_id     | creation_time            | user_email       | error_result                        |
+------------+--------------------------+------------------+-------------------------------------+
| bquxjob_1  | 2020-10-10 00:00:00 UTC  | abc@example.com  | Column 'col1' has mismatched type...|
| bquxjob_2  | 2020-10-11 00:00:00 UTC  | xyz@example.com  | Column 'col1' has mismatched type...|
| bquxjob_3  | 2020-10-11 00:00:00 UTC  | bob@example.com  | Column 'col1' has mismatched type...|
+------------+--------------------------+------------------+-------------------------------------+

장기 실행 작업 목록 쿼리

다음 예시는 30분 이상 RUNNING 또는 PENDING 상태인 장기 실행 작업 목록을 보여줍니다.

SELECT
  job_id,
  job_type,
  state,
  creation_time,
  start_time,
  user_email
 FROM `region-REGION_NAME`.INFORMATION_SCHEMA.JOBS
 WHERE
  state!="DONE" AND
  creation_time <= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 MINUTE)
ORDER BY
  creation_time ASC;

결과는 다음과 비슷합니다.

+--------+----------+---------+--------------------------------+--------------------------------+------------------+
| job_id | job_type | state   | creation_time                  | start_time                     | user_email       |
+--------+----------+---------+--------------------------------+--------------------------------+------------------+
| bquxjob_1  | QUERY    | RUNNING | 2023-05-03 05:07:22.818000 UTC | 2023-05-03 05:07:22.905000 UTC | abc@example.com  |
| bquxjob_2  | QUERY    | PENDING | 2023-05-01 02:05:47.925000 UTC | 2023-05-01 02:05:47.998000 UTC | xyz@example.com  |
| bquxjob_3  | QUERY    | PENDING | 2023-05-01 02:05:47.925000 UTC | 2023-05-01 02:05:47.998000 UTC | abc@example.com  |
+--------+----------+---------+--------------------------------+--------------------------------+------------------+

짧은 쿼리에 최적화된 모드를 사용하는 쿼리

다음 예시는 BigQuery에서 작업을 만들지 않은 짧은 쿼리에 최적화 모드에서 실행된 쿼리 목록을 보여줍니다.

SELECT
 job_id,
FROM
 `region-REGION_NAME`.INFORMATION_SCHEMA.JOBS
WHERE
 TIMESTAMP_TRUNC(creation_time, DAY) = '2024-06-12'
 AND job_creation_reason.code IS NULL
LIMIT 3;

다음과 같은 결과가 표시됩니다.

+-----------+
| job_id    |                                          |
+-----------+
| bquxjob_1 |
| bquxjob_2 |
| bquxjob_3 |
+-----------+

다음 예시는 BigQuery에서 작업을 만들지 않은 짧은 쿼리에 최적화 모드에서 실행된 쿼리에 관한 정보를 보여줍니다.

SELECT
 job_id,
 statement_type,
 priority,
 cache_hit,
 job_creation_reason.code AS job_creation_reason_code,
 total_bytes_billed,
 total_bytes_processed,
 total_slot_ms,
 state,
 error_result.message AS error_result_message,
FROM
 `region-REGION_NAME`.INFORMATION_SCHEMA.JOBS
WHERE
 TIMESTAMP_TRUNC(creation_time, DAY) = '2024-06-12'
 AND job_id = '2Lm09bHxDEsoVK8zwzWJomLHU_Ud%1910479b151' -- queryId

참고: 이 쿼리에 대한 작업이 생성되지 않은 경우 job_id 필드에 쿼리의 queryId가 포함됩니다.

다음과 같은 결과가 표시됩니다.

+-----------+----------------+-------------+-----------+--------------------------+--------------------+---------------------+---------------+-------+----------------------+
| job_id    | statement_type | priority    | cache_hit | job_creation_reason_code | total_bytes_billed | total_bytes_processed | total_slot_ms | state | error_result_message |
+-----------+----------------+-------------+-----------+--------------------------+--------------------+---------------------+---------------+-------+----------------------+
| bquxjob_1 | SELECT         | INTERACTIVE | false     | null                     | 161480704          | 161164718             | 3106          | DONE  | null                 |
+-----------+----------------+-------------+-----------+--------------------------+--------------------+---------------------+---------------+-------+----------------------+

다음 예시는 BigQuery에서 작업을 만든 짧은 쿼리에 최적화 모드에서 실행된 쿼리 목록을 보여줍니다.

SELECT
 job_id,
 job_creation_reason.code AS job_creation_reason_code
FROM
 `region-REGION_NAME`.INFORMATION_SCHEMA.JOBS
WHERE
 TIMESTAMP_TRUNC(creation_time, DAY) = '2024-06-12'
 AND job_creation_reason.code IS NOT NULL
 AND job_creation_reason.code != 'REQUESTED'
LIMIT 3

다음과 같은 결과가 표시됩니다.

+-----------+--------------------------+
| job_id    | job_creation_reason_code |
+-----------+--------------------------+
| bquxjob_1 | LARGE_RESULTS            |
| bquxjob_2 | LARGE_RESULTS            |
| bquxjob_3 | LARGE_RESULTS            |
+-----------+--------------------------+

사용자 ID당 처리되는 바이트 수

다음 예시는 사용자당 쿼리 작업에 대해 청구되는 총 바이트를 보여줍니다.

SELECT
  user_email,
  SUM(total_bytes_billed) AS bytes_billed
FROM
  `region-REGION_NAME`.INFORMATION_SCHEMA.JOBS
WHERE
  job_type = 'QUERY'
  AND statement_type != 'SCRIPT'
GROUP BY
  user_email;

참고: JOBS 뷰에 대해 스키마 문서에서 total_bytes_billed 열에 대한 주의 사항을 참조하세요.

다음과 같은 결과가 표시됩니다.

+---------------------+--------------+
| user_email          | bytes_billed |
+---------------------+--------------+
| bob@example.com     | 2847932416   |
| alice@example.com   | 1184890880   |
| charles@example.com | 10485760     |
+---------------------+--------------+

처리된 바이트의 시간별 분류

다음 예시는 쿼리 작업에 대해 청구되는 총 바이트를 시간별 간격으로 보여줍니다.

SELECT
  TIMESTAMP_TRUNC(end_time, HOUR) AS time_window,
  SUM(total_bytes_billed) AS bytes_billed
FROM
  `region-REGION_NAME`.INFORMATION_SCHEMA.JOBS
WHERE
  job_type = 'QUERY'
  AND statement_type != 'SCRIPT'
GROUP BY
  time_window
ORDER BY
  time_window DESC;

결과는 다음과 비슷합니다.

+-------------------------+--------------+
| time_window             | bytes_billed |
+-------------------------+--------------+
| 2022-05-17 20:00:00 UTC | 1967128576   |
| 2022-05-10 21:00:00 UTC | 0            |
| 2022-04-15 17:00:00 UTC | 41943040     |
+-------------------------+--------------+

테이블당 쿼리 작업 수

다음 예시는 my_project에 쿼리된 각 테이블이 쿼리 작업으로 참조된 횟수를 보여줍니다.

SELECT
  t.project_id,
  t.dataset_id,
  t.table_id,
  COUNT(*) AS num_references
FROM
  `region-REGION_NAME`.INFORMATION_SCHEMA.JOBS, UNNEST(referenced_tables) AS t
GROUP BY
  t.project_id,
  t.dataset_id,
  t.table_id
ORDER BY
  num_references DESC;

결과는 다음과 비슷합니다.

+------------+------------+----------+----------------+
| project_id | dataset_id | table_id | num_references |
+------------+------------+----------+----------------+
| my_project | dataset1   | orders   | 58             |
| my_project | dataset1   | products | 40             |
| other_proj | dataset1   | accounts | 12             |
+------------+------------+----------+----------------+

프로젝트당 레거시 SQL 쿼리 작업 수

INFORMATION_SCHEMA의 'query_dialect' 필드는 2025년 5월부터 사용할 수 있습니다. 다음 예는 프로젝트에서 실행되는 기존 SQL 쿼리 작업 수를 보여줍니다.

SELECT
  project_id,
  -- Implicitly defaulted to LegacySQL since the query dialect was not specified
  -- in the request.
  COUNTIF(query_dialect = 'DEFAULT_LEGACY_SQL') AS default_legacysql_query_jobs,
  -- Explicitly requested LegacySQL.
  COUNTIF(query_dialect = 'LEGACY_SQL') AS legacysql_query_jobs,
FROM
  `region-REGION_NAME`.INFORMATION_SCHEMA.JOBS
WHERE
  query_dialect = 'DEFAULT_LEGACY_SQL'
  OR query_dialect = 'LEGACY_SQL'
GROUP BY
  project_id
ORDER BY
  default_legacysql_query_jobs DESC,
  legacysql_query_jobs DESC;

테이블당 쿼리 및 로드 작업으로 수정된 파티션 수

다음 예시에서는 테이블마다 DML 문과 로드 작업이 있는 쿼리로 수정된 파티션 수를 보여줍니다. 이 쿼리에는 복사 작업의 total_modified_partitions가 표시되지 않습니다.

SELECT
  destination_table.table_id,
  SUM(total_modified_partitions) AS total_modified_partitions
FROM
  `region-REGION_NAME`.INFORMATION_SCHEMA.JOBS
WHERE
  DATE(creation_time, "America/Los_Angeles") = CURRENT_DATE()
GROUP BY
  table_id
ORDER BY
  total_modified_partitions DESC

프로젝트별로 비용이 가장 많이 드는 쿼리

다음 예시에는 슬롯 사용 시간별로 my_project에서 비용이 가장 많이 드는 쿼리가 나와 있습니다.

SELECT
 job_id,
 query,
 user_email,
 total_slot_ms
FROM `my_project`.`region-REGION_NAME`.INFORMATION_SCHEMA.JOBS
WHERE EXTRACT(DATE FROM  creation_time) = current_date()
ORDER BY total_slot_ms DESC
LIMIT 3

다음 예시로 처리된 데이터별로 비용이 가장 많이 드는 쿼리를 나열할 수도 있습니다.

SELECT
 job_id,
 query,
 user_email,
 total_bytes_processed
FROM `my_project`.`region-REGION_NAME`.INFORMATION_SCHEMA.JOBS
WHERE EXTRACT(DATE FROM  creation_time) = current_date()
ORDER BY total_bytes_processed DESC
LIMIT 3

두 예시 중 하나의 결과는 다음과 비슷합니다.

+-----------+---------------------------------+-----------------------+---------------+
| job_id    | query                           | user_email            | total_slot_ms |
+-----------+---------------------------------+--------------------------+------------+
| bquxjob_1 | SELECT ... FROM dataset.table1  | bob@example.com       | 80,000        |
| bquxjob_2 | SELECT ... FROM dataset.table2  | alice@example.com     | 78,000        |
| bquxjob_3 | SELECT ... FROM dataset.table3  | charles@example.com   | 75,000        |
+-----------+---------------------------------+-----------------------+---------------+

리소스 경고에 대한 세부정보 가져오기

리소스 초과 오류 메시지가 표시되면 일정 기간의 쿼리를 조회할 수 있습니다.

SELECT
  query,
  query_info.resource_warning
FROM
  `region-REGION_NAME`.INFORMATION_SCHEMA.JOBS
WHERE
 creation_time BETWEEN TIMESTAMP("2022-12-01")
 AND TIMESTAMP("2022-12-08")
 AND query_info.resource_warning IS NOT NULL
LIMIT 3;

날짜별로 그룹화된 리소스 경고 모니터링

리소스 초과 오류 메시지가 표시되면 날짜별로 그룹화된 리소스 경고의 총 개수를 모니터링하여 워크로드에 변경이 있는지 확인할 수 있습니다.

WITH resource_warnings AS (
  SELECT
    EXTRACT(DATE FROM creation_time) AS creation_date
  FROM
    `region-REGION_NAME`.INFORMATION_SCHEMA.JOBS
  WHERE
    creation_time >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 14 DAY)
    AND query_info.resource_warning IS NOT NULL
)
SELECT
  creation_date,
  COUNT(1) AS warning_counts
FROM
  resource_warnings
GROUP BY creation_date
ORDER BY creation_date DESC;

쿼리의 슬롯 사용량 및 비용 예상

다음 예시에서는 estimated_runnable_units를 사용하여 각 작업의 평균 슬롯과 최대 슬롯을 계산합니다.

예약이 없으면 reservation_idNULL입니다.

SELECT
  project_id,
  job_id,
  reservation_id,
  EXTRACT(DATE FROM creation_time) AS creation_date,
  TIMESTAMP_DIFF(end_time, start_time, SECOND) AS job_duration_seconds,
  job_type,
  user_email,
  total_bytes_billed,

  -- Average slot utilization per job is calculated by dividing total_slot_ms by the millisecond duration of the job

  SAFE_DIVIDE(job.total_slot_ms,(TIMESTAMP_DIFF(job.end_time, job.start_time, MILLISECOND))) AS job_avg_slots,
  query,

  -- Determine the max number of slots used at ANY stage in the query.
  -- The average slots might be 55. But a single stage might spike to 2000 slots.
  -- This is important to know when estimating number of slots to purchase.

  MAX(SAFE_DIVIDE(unnest_job_stages.slot_ms,unnest_job_stages.end_ms - unnest_job_stages.start_ms)) AS jobstage_max_slots,

  -- Check if there's a job that requests more units of works (slots). If so you need more slots.
  -- estimated_runnable_units = Units of work that can be scheduled immediately.
  -- Providing additional slots for these units of work accelerates the query,
  -- if no other query in the reservation needs additional slots.

  MAX(unnest_timeline.estimated_runnable_units) AS estimated_runnable_units
FROM `region-REGION_NAME`.INFORMATION_SCHEMA.JOBS AS job
  CROSS JOIN UNNEST(job_stages) as unnest_job_stages
  CROSS JOIN UNNEST(timeline) AS unnest_timeline
WHERE project_id = 'my_project'
  AND statement_type != 'SCRIPT'
  AND DATE(creation_time) BETWEEN DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY) AND CURRENT_DATE()
GROUP BY 1,2,3,4,5,6,7,8,9,10
ORDER BY job_id;

예를 들어 결과는 다음과 비슷합니다.

+-----------+-----------+----------------+---------------+----------------------+----------+-----------------+--------------------+--------------+--------------------------------+--------------------+--------------------------+
|project_id | job_id    | reservation_id | creation_date | job_duration_seconds | job_type | user_email      | total_bytes_billed | job_avg_slots| query                          | jobstage_max_slots | estimated_runnable_units |
+-----------+-----------+----------------+---------------+----------------------+----------+-----------------+--------------------+--------------+--------------------------------+--------------------+--------------------------+
| project1  | bquxjob1  | reservation1   | 2020-10-10    | 160                  | LOAD     | abc@example.com | 161480704          | 2890         | SELECT ... FROM dataset.table1 | 2779.1534          | 8293                     |
| project1  | bquxjob2  | reservation2   | 2020-12-10    | 120                  | LOAD     | abc@example.com | 161480704          | 2890         | SELECT ... FROM dataset.table1 | 2779.1534          | 8768                     |
| project1  | bquxjob3  | reservation1   | 2020-12-10    | 120                  | LOAD     | abc@example.com | 161480704          | 2890         | SELECT ... FROM dataset.table1 | 1279.1534          | 8738                     |
+-----------+-----------+----------------+---------------+----------------------+----------+-----------------+--------------------+--------------+--------------------------------+--------------------+--------------------------+

쿼리 성능 통계 보기

다음 예시에서는 Google Cloud 콘솔의 쿼리 실행 그래프에 연결되는 URL과 함께 지난 30일 동안 프로젝트의 성능 통계가 있는 모든 쿼리 작업을 반환합니다.

SELECT
  `bigquery-public-data`.persistent_udfs.job_url(
    project_id || ':us.' || job_id) AS job_url,
  query_info.performance_insights
FROM
  `region-REGION_NAME`.INFORMATION_SCHEMA.JOBS_BY_PROJECT
WHERE
  DATE(creation_time) >= CURRENT_DATE - 30 -- scan 30 days of query history
  AND job_type = 'QUERY'
  AND state = 'DONE'
  AND error_result IS NULL
  AND statement_type != 'SCRIPT'
  AND EXISTS ( -- Only include queries which had performance insights
    SELECT 1
    FROM UNNEST(
      query_info.performance_insights.stage_performance_standalone_insights
    )
    WHERE slot_contention OR insufficient_shuffle_quota
    UNION ALL
    SELECT 1
    FROM UNNEST(
      query_info.performance_insights.stage_performance_change_insights
    )
    WHERE input_data_change.records_read_diff_percentage IS NOT NULL
  );

메타데이터 새로고침 작업 보기

다음 예에서는 지난 6시간 동안의 메타데이터 새로고침 작업을 보여줍니다.

SELECT
 *
FROM
 `region-REGION_NAME`.INFORMATION_SCHEMA.JOBS_BY_PROJECT
WHERE
 job_id LIKE '%metadata_cache_refresh%'
 AND creation_time > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 6 HOUR)
ORDER BY start_time desc
LIMIT 10;

REGION_NAME을 현재 리전으로 바꿉니다.

동일한 쿼리의 시간 경과에 따른 성능 분석

다음 예시에서는 지난 7일 동안 동일한 쿼리를 실행한 작업 중 가장 느린 작업 10개를 반환합니다.

DECLARE querytext STRING DEFAULT(
  SELECT query
  FROM `region-REGION_NAME`.INFORMATION_SCHEMA.JOBS
  WHERE job_id = 'JOB_ID'
  LIMIT 1
);

SELECT
  start_time,
  end_time,
  project_id,
  job_id,
  TIMESTAMP_DIFF(end_time, start_time, SECOND) AS run_secs,
  total_bytes_processed / POW(1024, 3) AS total_gigabytes_processed,
  query
FROM
  `region-REGION_NAME`.INFORMATION_SCHEMA.JOBS
WHERE
  query = querytext
  AND total_bytes_processed > 0
  AND creation_time >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)
ORDER BY 5 DESC
LIMIT 3;

JOB_ID를 분석 중인 쿼리를 실행한 job_id로 바꿉니다.

오늘 가장 많은 바이트를 스캔한 상위 5개 작업

다음 예시에서는 오늘 날짜의 조직에서 가장 많은 바이트를 검색한 작업 5개를 찾는 방법을 보여줍니다. 로드, 내보내기, 쿼리와 같은 추가 정보를 쿼리하려면 statement_type을 추가로 필터링할 수 있습니다.

SELECT
  job_id,
  user_email,
  total_bytes_billed
FROM
  `region-REGION_NAME`.INFORMATION_SCHEMA.JOBS_BY_ORGANIZATION
WHERE
  EXTRACT(DATE FROM  creation_time) = current_date()
ORDER BY
  total_bytes_billed DESC
LIMIT 3;

결과는 다음과 비슷합니다.

+--------------+--------------+---------------------------+
| job_id       |  user_email  |  total_bytes_billed       |
+--------------+--------------+---------------------------+
| bquxjob_1    |  abc@xyz.com |    999999                 |
| bquxjob_2    |  def@xyz.com |    888888                 |
| bquxjob_3    |  ghi@xyz.com |    777777                 |
+--------------+--------------+---------------------------+

대기 중이거나 실행 중인 작업 보기

SELECT
  job_id,
  creation_time,
  query
FROM
  `region-REGION_NAME`.INFORMATION_SCHEMA.JOBS_BY_USER
WHERE
  state != 'DONE';

결과는 다음과 비슷합니다.

+--------------+---------------------------+---------------------------------+
| job_id       |  creation_time            |  query                          |
+--------------+---------------------------+---------------------------------+
| bquxjob_1    |  2019-10-10 00:00:00 UTC  |  SELECT ... FROM dataset.table1 |
| bquxjob_2    |  2019-10-10 00:00:01 UTC  |  SELECT ... FROM dataset.table2 |
| bquxjob_3    |  2019-10-10 00:00:02 UTC  |  SELECT ... FROM dataset.table3 |
+--------------+---------------------------+---------------------------------+

내보내기 작업으로 처리된 바이트 가져오기

다음 예시에서는 EXTRACT 작업 유형의 total_bytes_processed 값을 계산합니다. 내보내기 작업 할당량에 대한 자세한 내용은 내보내기 작업 할당량 정책을 참고하세요. 처리된 총 바이트를 사용하면 집계 사용량을 모니터링하고 내보내기 작업을 일일 50TB 한도 이하로 유지할 수 있습니다.

SELECT
    DATE(creation_time) as day,
    project_id as source_project_id,
    SUM(total_bytes_processed) AS total_bytes_processed
 FROM
   `region-REGION_NAME`.INFORMATION_SCHEMA.JOBS
 WHERE
    creation_time BETWEEN TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 8 DAY) AND CURRENT_TIMESTAMP()
    AND job_type = "EXTRACT"
GROUP BY
    day,
    source_project_id
ORDER BY
    day DESC;

복사 작업 사용량 가져오기

복사 작업에 대한 자세한 내용은 테이블 복사를 참고하세요. 다음은 복사 작업의 사용량을 가져오는 예시입니다.

SELECT
    DATE(creation_time) as day,
    project_id as source_project_id,
CONCAT(destination_table.project_id,":",destination_table.dataset_id,".",destination_table.table_id) as destination_table,
    COUNT(job_id) AS copy_job_count
 FROM
   `region-REGION_NAME`.INFORMATION_SCHEMA.JOBS
 WHERE
    creation_time BETWEEN TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 8 DAY) AND CURRENT_TIMESTAMP()
    AND job_type = "COPY"
GROUP BY
    day,
    source_project_id,
    destination_table
ORDER BY
    day DESC;

Apache Iceberg 스토리지 최적화를 위한 BigQuery 테이블 사용량 가져오기

다음 예는 Iceberg 테이블 스토리지 최적화의 사용량을 보여줍니다.

SELECT
    job_id, reservation_id, edition,
    total_slot_ms, total_bytes_processed, state
FROM `region-REGION_NAME`.INFORMATION_SCHEMA.JOBS
WHERE creation_time > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 6 HOUR)
    AND user_email = "bigquery-adminbot@system.gserviceaccount.com"
    AND query LIKE "CALL BQ.OPTIMIZE_STORAGE(%)";

Iceberg 테이블 내보내기 테이블 메타데이터 사용량 가져오기

다음 예는 Iceberg EXPORT TABLE METADATA FROM의 사용법을 보여줍니다.

SELECT
   job_id,
   user_email,
   start_time,
   end_time,
   TIMESTAMP_DIFF(end_time, start_time, SECOND) AS duration_seconds,
   total_bytes_processed,
   reservation_id,
   CASE
     WHEN reservation_id IS NULL THEN 'PAYG (On-demand)'
     WHEN reservation_id != '' THEN 'Reservation'
     ELSE 'Unknown'
   END AS compute_type,
   query
 FROM
   `region-REGION_NAME`.INFORMATION_SCHEMA.JOBS
 WHERE
   job_type = 'QUERY'
   AND end_time IS NOT NULL
   -- Filter for queries containing the specified pattern (case-insensitive)
   AND REGEXP_CONTAINS(LOWER(query), r"export table metadata from")
 ORDER BY
   start_time DESC
 LIMIT 3;

관리 리소스 차트의 슬롯 사용 동작 일치

관리 리소스 차트의 정보와 유사한 슬롯 사용 동작을 살펴보려면 INFORMATION_SCHEMA.JOBS_TIMELINE를 쿼리합니다.