BigQueryは従量課金なので、下手なクエリを打って無駄にお金を溶かしたくはないものです。
操作ミスで高いクエリを実行してしまう大きな理由として、パーティション指定のし忘れがあると思います。
パーティション指定をし忘れを防ぐ為に、トラウマになるぐらいのパーティションを指定する反復練習をするのも一つの手ですが、パーティションを指定しないとクエリが実行されない設定をするという手もあります。
下記のように「–require_partition_filter」を指定してテーブルを作成した上で、
bq mk --require_partition_filter --time_partitioning_type DAY {DATASET}.{TABLE} {SCHEMA}.json
クエリを実行すると、
bq query --nouse_legacy_sql "SELECT * FROM \`{DATASET}.{TABLE}\`
このように怒られます。
Cannot query over table '{DATASET}.{TABLE}' without a filter over column(s) '_PARTITION_LOAD_TIME',
'_PARTITIONDATE', '_PARTITIONTIME' that can be used for partition elimination
これで安心してクエリが叩けますね。
にしても、パーティション指定って面倒臭いですよね。
パーティション指定をした上で、WHERE句に時系列のカラムを指定するとか、パーティションを指定してバルクインサートするとか。
そんな方には「–time_partitioning_field {カラム名}」を指定してテーブルを作成するのがオススメです。
bq mk --require_partition_filter --time_partitioning_type DAY --time_partitioning_field timestamp {DATASET}.${TABLE} {SCHEMA}.json
仮に指定したカラムを下記のテーブルのtimestampにしたとしましょう。
[
{ "name" : "timestamp", "type" : "TIMESTAMP", "mode" : "NULLABLE" },
{ "name" : "user_id", "type" : "INT64", "mode" : "NULLABLE" }
]
まず作成したテーブルに下記のCSVをバルクインサートしてみます。
2018-10-20 12:00:00, 123
2018-10-21 12:00:00, 456
2018-10-22 12:00:00, 789
bq load {DATASET}.${TABLE} xxx.csv
すると、timestampを軸にパーティショニングがされて、 下記のようにloadされます。
{DATASET}.${TABLE}$20181020 に 「2018-10-20 12:00:00, 123」 {DATASET}.${TABLE}$20181021 に 「2018-10-21 12:00:00, 456」 {DATASET}.${TABLE}$20181022 に 「2018-10-22 12:00:00, 789」
さらにそのデータに対して下記のようにクエリを実行すると、
bq query --nouse_legacy_sql "SELECT * FROM \`{DATASET}.{TABLE}\` WHERE timestamp >= TIMESTAMP('2018-10-20') AND timestamp < TIMESTAMP('2018-10-21')
パーティション指定が不要で、しかもパーティションの20181020のみを参照してくれます。
テーブル作成の指定により、実装の工数やクエリの文字数など削減できると思うので、 考慮して指定してみるといいと思います。
株式会社grasys(グラシス)は、技術が好きで一緒に夢中になれる仲間を募集しています。
grasysは、大規模・高負荷・高集積・高密度なシステムを多く扱っているITインフラの会社です。Google Cloud (GCP)、Amazon Web Services (AWS)、Microsoft Azureの最先端技術を活用してクラウドインフラやデータ分析基盤など、ITシステムの重要な基盤を設計・構築し、改善を続けながら運用しています。
お客様の課題解決をしながら技術を広げたい方、攻めのインフラ技術を習得したい方、とことん技術を追求したい方にとって素晴らしい環境が、grasysにはあります。
お気軽にご連絡ください。