インフラ

BigQueryの使い方:コンソールとbqコマンドの初回操作からクエリ実行まで

手元のCSVをBigQueryへ載せてSQLを流したい。やることの見当はついているのに、プロジェクトとデータセットとテーブルの関係、ロケーションの指定、bqコマンドの認証あたりで手が止まる。この記事では、コンソールで最初に触る場所、bqコマンドの導入と認証、データセット作成からデータ投入、スキャン量を確かめてからのクエリ実行、そしてつまずきやすい権限とロケーションまでを、2026年8月17日時点の公式ドキュメントの実測をもとに順番に追いました。仕組みそのものと採用してよいかの判断はBigQueryの仕組みと採用判断をまとめた解説に譲り、ここでは手を動かす側だけを扱います。

まとめ:先に決める3つと、初回にほぼ全員がつまずく2箇所

BigQueryを触り始める前に決めるのは3つだけです。1つ目は、課金アカウントを紐づけずサンドボックスで始めるか、課金を有効にして始めるか。2つ目は、データセットをどのロケーションに置くか。3つ目は、コンソール中心で進めるかbqコマンド中心で進めるかの主戦場です。この3つが決まっていれば、テーブル作成もクエリ実行も迷いません。

逆に、初回にほぼ全員が引っかかるのは権限とロケーションの2箇所です。権限は、ジョブを実行する権限とデータを読む権限が別々のロールに分かれているところで詰まります。ロケーションは、データセットを作った後で変更できず、ロケーションの違うテーブル同士はクエリで結合できないという仕様に後から気づいて詰まる。

手順の骨格は、プロジェクトを用意してデータセットを作り、テーブルへデータを読み込み、クエリを実行する。この4段です。使うコマンドは bq mkbq loadbq query の3つに集約されます。コンソールでも同じ4段を画面から実行するだけなので、どちらから入っても覚える概念は変わりません。

BigQueryをコンソールとbqコマンドのどちらから始めるかを決める

入口は2つあります。ブラウザのGoogle Cloudコンソールと、ローカルへ入れるbqコマンドです。両方を同時に覚えようとすると手が止まるため、最初にどちらを主戦場にするかを決めてしまうほうが早く進みます。

コンソールで最初に触るのはエクスプローラと実行画面とジョブ履歴です

コンソールのBigQuery画面で覚える場所は3つに絞れます。左のエクスプローラは、プロジェクト・データセット・テーブルという3階層を木構造で表示する場所で、テーブルを選ぶと右側にスキーマ・詳細・プレビューのタブが出ます。プレビューはクエリを実行せずに中身を確認できるため、料金が発生しないままデータの形を確かめられる。

2つ目はクエリエディタです。SQLを書いている途中でエディタの右上に「このクエリを実行すると◯◯を処理します」という推定バイト数が表示されます。この数字が、そのまま課金対象のスキャン量になる。実行ボタンを押す前に必ずここを見る習慣をつけると、想定外の請求はかなりの部分を防げます。

3つ目はジョブ履歴です。実行したクエリ、読み込み、エクスポートはすべてジョブとして記録され、処理バイト数と所要時間、失敗したジョブのエラー内容を後から追えます。自分のジョブとプロジェクト全体を切り替えられるので、複数人で触っていても誰のクエリが重かったのか分かる。

bqコマンドはGoogle Cloud CLIに同梱され認証は2手で終わる

bqはBigQuery専用のコマンドラインツールで、単体では配布されずGoogle Cloud CLIに同梱されています。2026年8月11日リリースの580.0系が最新で、CLIをインストールすると gcloud と一緒に bq も入る。ブラウザのCloud Shellを使う場合はインストール自体が不要で、開いた時点でbqが使える状態になっています。

認証は2手です。ブラウザでGoogleアカウントにログインして資格情報をローカルへ保存し、続けて既定のプロジェクトを設定する。

gcloud auth login
gcloud config set project my-project-id
bq ls

3行目の bq ls はデータセットの一覧表示で、疎通確認を兼ねます。空の結果が返れば接続はできていて、まだデータセットが1つもない状態です。エラーが返る場合は認証かプロジェクトIDのどちらかで、権限の問題はこの段階では出ません。

サンドボックスで始めると60日の有効期限と3つの機能制限が後から効く

課金アカウントを紐づけずに始められるのがBigQueryサンドボックスです。無料枠はアクティブストレージが毎月10GB、クエリのデータ処理が毎月1TBで、この範囲なら費用は発生しません。ただし制約が3つあります。データのストリーミング、DMLステートメント、BigQuery Data Transfer Serviceがいずれも使えない。

DMLが使えない制限は見た目以上に効きます。INSERT・UPDATE・DELETEが通らないため、データの投入は読み込みジョブかクエリ結果の書き出しに限られる。さらに、テーブル・ビュー・パーティションは60日で自動的に期限切れになり、すべてのデータセットに既定のテーブル有効期限が設定されます。2か月放置した検証環境は中身が消えている前提で考えてください。

SQLの書き味を試すだけならサンドボックスで足ります。投入経路や更新処理まで検証したいなら、最初から課金を有効にしたうえで後述の課金バイト上限で歯止めをかけてください。

データセットの作成からテーブルへのデータ投入までの操作手順を追う

プロジェクトの下にデータセット、データセットの下にテーブルという階層です。データセットはテーブルの入れ物であると同時に、アクセス権とロケーションを持つ単位でもあります。ここで決めた設定が後の制約になるため、最初の1回だけは意識して作ってください。

データセットの作成時にロケーションを決めると後から変更できません

データセットは bq mk で作ります。ロケーションは作成時にしか指定できません。

bq --location=asia-northeast1 mk -d my_dataset
bq show --format=prettyjson my_dataset

公式ドキュメントは、データセットを作成した後でそのロケーションを変更することはできないと明記しています。加えて、異なるロケーションのテーブルを参照するクエリは失敗し、単一リージョンのロケーションはマルチリージョンのロケーションと一致しない扱いになる。東京リージョンのデータセットと、うっかり既定のまま作られた米国マルチリージョンのデータセットは、同じクエリの中でJOINできません。

間違えた場合の直し方は1つで、正しいロケーションで作り直してデータを移送します。ロケーション名は、東京が asia-northeast1、大阪が asia-northeast2、米国マルチリージョンが US、欧州マルチリージョンが EU です。国内のデータなら東京か大阪へ寄せ、以降そこから動かさない方針を先に決めてしまうのが安全でしょう。

ローカルとCloud Storage経由でbq loadの書き方が変わる

データ投入は bq load です。ローカルのCSVをそのまま読み込む場合は、パスを直接渡します。

bq load --source_format=CSV --autodetect --skip_leading_rows=1 my_dataset.sales ./sales.csv

ファイルサイズが大きい場合や、複数ファイルをまとめて入れたい場合はCloud Storage経由に切り替えます。バケットへ置いてからワイルドカードで指定すると、分割された出力をそのまま1テーブルへ流し込める。

bq load --source_format=NEWLINE_DELIMITED_JSON my_dataset.events gs://my-bucket/events/2026-08-*.json

ローカル読み込みは手軽ですが、経路が端末を通るぶん転送に時間がかかります。定期的に入れるデータであれば、置き場をCloud Storageに固定して読み込みジョブだけを回す形へ早めに移したほうが、後で自動化するときに書き換える箇所が減る。JSONは改行区切り形式が前提で、配列を1ファイルにまとめた通常のJSONは読み込めません。

スキーマの自動検出に任せてよい場面と列定義を明示して書くべき場面

--autodetect はファイルの先頭部分をサンプリングして列名と型を推定する仕組みです。手元のCSVを一度眺めるだけなら、これで十分に用が足ります。

一方、列定義を明示すべき場面もはっきりしています。数値に見えるが先頭のゼロを保持したい社員番号や商品コード、空欄が多く型が揺れる列、日付の書式が混在しているファイル。こうした列は推定が外れると文字列と整数のどちらかに倒れてしまい、後続のクエリで型変換の手間が延々と続きます。スキーマはJSONファイルに書いて渡せます。

bq load --source_format=CSV --skip_leading_rows=1 my_dataset.sales ./sales.csv ./schema.json

判断の目安は、そのテーブルを二度以上使うかどうかです。使い捨ての確認なら自動検出、繰り返し参照するテーブルなら列定義を書く。この線引きで迷うことはなくなります。

クエリを実行する前にドライランでスキャン量を確かめる手順を作る

BigQueryのオンデマンド課金は、読んだバイト数に対して発生します。単価は1TiBあたり6.25ドル(Iowa基準・リージョンで異なる)で、無料枠は毎月1TBです。実行前に量を確かめる手順を最初に体へ入れておくと、後の請求で驚くことがなくなります。課金体系そのものの分解はBigQueryの料金の内訳と監視方法をまとめた解説で扱っています。

ドライランを使えば課金対象のバイト数を実行せずに見積もれます

コンソールならエディタ右上の推定バイト数、bqコマンドなら --dry_run です。クエリは実行されず、処理予定のバイト数だけが返ります。

bq query --use_legacy_sql=false --dry_run \
'SELECT order_date, SUM(amount) FROM `my_project.my_dataset.sales` GROUP BY 1'

見積もりが想定より1桁大きいときは、たいてい SELECT * を書いているか、パーティション列を条件に入れ忘れています。列指向で保存されているため、読む列を絞るだけでスキャン量はそのまま減る。

それでも事故を完全には防げないので、上限も併せて設定します。--maximum_bytes_billed を付けると、その量を超えるクエリは実行前に失敗します。

bq query --use_legacy_sql=false --maximum_bytes_billed=10000000000 \
'SELECT order_date, SUM(amount) FROM `my_project.my_dataset.sales` GROUP BY 1'

クエリ結果をテーブルへ書き出すときの指定と一時テーブルの扱い方

クエリ結果は、指定しなければ一時テーブルに置かれ、一定期間で消えます。残したい結果は書き出し先を明示してください。

bq query --use_legacy_sql=false --destination_table my_dataset.daily_sales --replace \
'SELECT order_date, SUM(amount) AS amount FROM `my_project.my_dataset.sales` GROUP BY 1'

--replace は毎回テーブルを作り直し、--append_table は末尾へ追記します。日次の集計を積み上げるなら追記、その日時点の全量を作り直すなら置き換え。取り違えると重複行が静かに増えていくので、書き出し系のコマンドはこの2つのどちらを使うかを決めてから書いてください。

実行したジョブの処理量と失敗理由はジョブ履歴とビューから追う

誰がどれだけ読んだかは INFORMATION_SCHEMA のジョブビューに残ります。コンソールのジョブ履歴で個別に追うこともできますが、月末に集計したいならSQLで引くほうが早い。

SELECT user_email, SUM(total_bytes_billed) AS billed_bytes
FROM `region-asia-northeast1`.INFORMATION_SCHEMA.JOBS_BY_PROJECT
WHERE creation_time >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
GROUP BY 1 ORDER BY 2 DESC

先頭の region- に続く部分はデータセットのロケーションと揃えます。東京のデータセットのジョブを米国のビューから引いても、結果は空で返ります。

GoogleSQLの基本文法とレガシーSQLから変わった点を押さえる

BigQueryのSQL方言は、以前は標準SQLと呼ばれていたものがGoogleSQLという名称になりました。社内に残る古いクエリはレガシーSQLで書かれていることがあり、記法が噛み合わないまま実行して構文エラーになるのが、SQL側の代表的なつまずきです。

テーブル参照はバッククォートで囲みドットで区切って書く記法です

GoogleSQLでは、プロジェクト・データセット・テーブルをドットでつなぎ、全体をバッククォートで囲みます。同じプロジェクト内ならプロジェクトIDは省略できる。レガシーSQLは角かっこで囲み、プロジェクトとデータセットの間はコロンで区切っていたため、見た目で判別できます。

-- GoogleSQL
SELECT * FROM `my_project.my_dataset.sales` LIMIT 10

-- レガシーSQL(古い記法)
SELECT * FROM [my_project:my_dataset.sales] LIMIT 10

bqコマンドで --use_legacy_sql=false を毎回書いているのはこの指定です。コンソールのエディタは既定でGoogleSQLなので、持ち込んだクエリが角かっこで書かれていたら、そこがエラーの原因だと当たりをつけられます。

配列と構造体はUNNESTで行に展開してから結合して扱う書き方

BigQueryのテーブルは、1つのセルに配列や構造体を持てます。イベントログやアプリの計測データを読み込むと、パラメータが配列で入っている形によく出会う。配列は UNNEST で行に展開してから結合します。

SELECT e.event_name, p.key, p.value.string_value
FROM `my_project.my_dataset.events` AS e,
UNNEST(e.event_params) AS p
WHERE p.key = 'page_title'

FROM句のカンマは、この文脈では相関結合として働きます。元の行が配列の要素数だけ増えるため、件数を数える集計では展開前と展開後のどちらで数えているかを意識してください。取り違えると、水増しされた行数をそのまま報告してしまいます。

パーティション列を条件に入れないと全期間を読んでしまう仕組み

日付でパーティション分割したテーブルは、WHERE句にパーティション列の条件を書いて初めて読む範囲が絞られます。条件を書かないと全期間が対象になり、テーブルが育つほどスキャン量が膨らむ。

SELECT COUNT(*) FROM `my_project.my_dataset.events`
WHERE event_date BETWEEN '2026-08-01' AND '2026-08-17'

絞り込みをさらに効かせたい場合はクラスタリングを併用します。よく条件に使う列を指定しておくと、同じ値のデータが物理的に近くへまとまり、読み飛ばせるブロックが増える。読む列を減らす、期間を絞る、この2つで大半のクエリは軽くなります。

権限とロケーションで出るエラーを切り分ける順番を先に決めておく

初回の詰まりどころが集中するのがここです。エラーメッセージは症状しか教えてくれないため、見る順番を先に決めておくと解決が早くなります。

クエリ実行の最小権限はjobUserとdataViewerの組み合わせ

BigQueryのIAMは、ジョブを実行する権限とデータへ到達する権限が分かれています。roles/bigquery.jobUser はプロジェクト内でジョブを実行する権限だけを与え、データそのものには手が届きません。roles/bigquery.dataViewer はテーブルデータのクエリ・エクスポート・複製とメタデータの閲覧を許可し、更新はできない。クエリを流すだけの利用者に渡す最小構成は、この2つの組み合わせです。

ロール できること 渡す相手
bigquery.jobUser ジョブ実行のみ 閲覧者(データ権限と併用)
bigquery.dataViewer データの読み取り 閲覧者
bigquery.user 実行とデータセット作成 分析担当
bigquery.dataEditor テーブルの作成と更新 基盤の構築担当
bigquery.admin 全リソースの管理 管理者のみ

「権限がない」と出たときは、ジョブ側とデータ側のどちらが欠けているかを切り分けてください。ジョブは起動するのにテーブルが見えないならデータ側、クエリの投入自体が拒否されるならジョブ側です。bigquery.admin を配って回ると、他人のジョブをキャンセルできる権限まで渡すことになります。

ロケーション不一致で出るエラーはデータセット側の設定を見て直す

「データセットが見つからない」という趣旨のエラーが出たのに、コンソールではデータセットが確かに存在している。この組み合わせを見たらロケーションを疑ってください。bqコマンドは --location の指定がデータセットのロケーションと食い違うと、そのロケーションの中に対象が無いという理由で失敗します。

確認は bq show --format=prettyjson my_dataset で、返ってきたJSONのlocationフィールドを見る。複数ロケーションのデータセットが混在しているなら、跨いだクエリは書けない前提で、どちらかへ寄せる移送を計画に入れてください。

費用の暴走はカスタムクォータと課金バイト上限の二段構えで止める

費用の歯止めは2つの層で掛けます。1つはプロジェクト単位・ユーザー単位で1日あたりのクエリ使用量に上限を設けるカスタムクォータ、もう1つは個々のクエリに掛ける課金バイト上限です。前者は組織として使いすぎを止め、後者は書き間違えた1本を止める。役割が違うので両方を入れてください。請求が跳ねてから設定する順番になりがちですが、テーブルを作った日に一緒に済ませてしまうのが確実です。

自力で進めてよい範囲と設計として固めるべき線引きをどこに置くか

ここまでの操作は、慣れれば半日で一通り通せます。問題は、どこまでを手元の試行で進めてよく、どこから設計として固めるべきかという線引きです。ここを曖昧にしたまま人数が増えると、後戻りのコストが跳ね上がります。

コンソールだけで進めてよいのは形の確認と単発の集計までに限る

コンソールで完結させてよいのは、データの形を確かめる作業と、その場限りの集計までです。画面から手で実行した処理は履歴には残るものの、再現するには誰かが同じ操作を繰り返すしかない。

作った結果を誰かに定期的に見せる段になったら、そこが一つ目の線です。BIツールへ接続して配る形にすると、閲覧者にBigQueryの権限を配らずに済みます。接続先の選定はLooker Studioの機能と料金・BigQuery連携の解説が判断材料になります。

bqコマンドとスクリプトへ移すのはデータ投入が定期化した時点

二つ目の線は、同じデータを二度目に入れるときです。手作業のアップロードは、回数が増えるほど入れ忘れと二重投入が起きます。bq load をシェルスクリプトにまとめ、Cloud Storageへの配置とセットで回す形に切り替えてください。スクリプトを自前で持たずに定期実行へ寄せるなら、BigQuery Data Transfer Serviceでの定期取り込みが選択肢になります。この時点でロケーションとスキーマは固定され、以降は変えにくくなるという意味でも、ここが設計を固める節目になります。

投入が安定してからSQLでの分析処理へ進むなら、学習まで同じSQLで完結させる道もあります。その範囲はBigQuery MLでモデルを学習する方法の解説に整理しました。

外部に任せるかどうかの判断は権限設計とロケーション決定より前に置く

三つ目の線は、部署をまたいでデータを集め始めるときです。誰にどのデータセットを見せるかという権限設計と、ロケーションをどこに寄せるかという決定は、どちらも後から変えるコストが高い。特にロケーションは作成後に変更できず、作り直しと移送が必要になります。この2点を決める前に、自社だけで進めるか外部の手を借りるかを判断してください。

判断の目安は明快です。データソースが3つ以内で、見せる相手が同じ部署に閉じているなら自力で足ります。ソースが業務システムをまたぎ、個人情報を含む列があり、閲覧範囲を部署ごとに分ける必要があるなら、権限設計とロケーションを決める段階から設計者を入れたほうが安く済む。当社ではデータ分析基盤構築・MLOps構築支援として、データセット設計から投入経路、権限とコスト管理までを含めた構築を請けています。体制の組み方とPoCからの進め方はBigQuery導入の手順と体制の解説を、他社がどの段階で成果を出したかはBigQueryの事例4類型の解説を参照してください。

逆に、見送ってよい場面もあります。扱うデータが数万行に収まり、更新が頻繁で、単一行の参照が処理の中心という条件が揃うなら、BigQueryを持ち出す前に既存のデータベースで足ります。スキャン課金の仕組みは大量のデータをまとめて読む処理に向いていて、小さなデータを何度も引く処理では利点が出ません。

よくある質問

BigQueryは無料で試せますか?

試せます。課金アカウントを紐づけないサンドボックスなら、アクティブストレージ毎月10GB、クエリのデータ処理毎月1TBの範囲で費用は発生しません。ただしデータのストリーミング、DMLステートメント、BigQuery Data Transfer Serviceが使えず、テーブル・ビュー・パーティションは60日で期限切れになります。投入経路や更新処理まで試すなら課金を有効にするほうが手戻りは少ないでしょう。

bqコマンドとコンソールはどちらを覚えるべきですか?

最初はコンソールで構いません。エクスプローラでデータの階層を目で見て理解できるぶん、概念の把握が早く進みます。同じ処理を二度目に実行する段になったらbqへ移ってください。覚える概念はどちらも同じで、プロジェクト・データセット・テーブルの3階層とジョブという単位だけです。

レガシーSQLで書かれた既存クエリは書き直しが必要ですか?

そのままでも実行はできますが、書き直しを勧めます。レガシーSQLは角かっことコロンでテーブルを参照する記法で、配列や構造体の扱いがGoogleSQLと噛み合いません。テーブル参照をバッククォートとドットに直すところから始めると、大半のクエリは通ります。

データセットのロケーションを後から変えられますか?

変えられません。公式ドキュメントは、データセットを作成した後でロケーションを変更することはできないと明記しています。加えて、異なるロケーションのテーブルを参照するクエリは失敗し、単一リージョンとマルチリージョンも一致しない扱いです。誤って作った場合は、正しいロケーションで作り直してデータを移送してください。

クエリ料金が想定より膨らむのを防ぐ方法はありますか?

3つの手を組み合わせてください。実行前にドライランか推定バイト数で量を確かめること、個々のクエリに課金バイト上限を掛けること、プロジェクト単位とユーザー単位で1日あたりの使用量にカスタムクォータを設けること。加えて SELECT * を避けて読む列を絞り、パーティション列を条件に入れる書き方を習慣にします。

関連記事

資料請求

RELATED POSTS 関連記事