プライバシーを重視したパフォーマンスの高いクエリを作成できるよう、以下のベスト プラクティスをお役立てください。
プライバシーとデータの精度
サンドボックス データに対するクエリを作成する
ベスト プラクティス: 本番環境の場合のみ、本番環境データをクエリする。
クエリの作成中は、可能な限りサンドボックス データを使用します。サンドボックス データを使用するジョブでは、差分チェックによってクエリ結果をフィルタリングできません。また、プライバシー チェックが行われないため、サンドボックス クエリの実行は迅速で、クエリの作成中により速い反復処理が可能になります。
実際のデータに対するクエリを作成する必要がある場合(マッチテーブルを使用する場合など)、行の重複を防止するには、クエリの反復処理で重複する可能性の低い期間と他のパラメータを選択してから、目的のデータ範囲に対してクエリを実行します。
過去の結果を慎重に確認する
ベスト プラクティス: 最近実行したクエリ間で結果セットが重複する可能性を減らす。
クエリ結果間にどれほどの差異があるかは、後にプライバシー チェックで結果が削除される可能性に影響します。つまり、最近返された結果セットによく似た 2 番目の結果セットは破棄される可能性が高くなります。
期間やキャンペーン ID などのクエリの主要パラメータを変更して、明らかな重複が発生する可能性を減らしましょう。
今日の日付のデータをクエリしない
ベスト プラクティス: 終了日が今日の日付のクエリを複数実行しない。
終了日が今日の日付と一致する複数のクエリを実行すると、多くの場合、行が除外されます。深夜 0 時直後に昨日の日付のデータに対するクエリの実行も同様です。
同じデータを必要以上にクエリしない
ベスト プラクティス:
- 開始日と終了日が他の期間と重複しないようにする。
- 重複する期間でクエリを実行するのではなく、独立したデータセットに対してクエリを実行し、その結果を BigQuery で集計する。
- クエリを再実行するのではなく、保存した結果を使用する。
- クエリ対象の期間ごとに一時テーブルを作成する。
Ads Data Hub では、同じデータをクエリできる合計回数が制限されているため、特定のデータにアクセスする回数を抑えましょう。
同じクエリ内で必要以上の数の集計を使用しない
ベスト プラクティス:
- 同一クエリ内の集計の数を最小限に抑える
- 可能であればクエリを書き直して複数の集計をひとつにまとめる
1 つのサブクエリ内で使用できるクロスユーザー集計の数は、最大 100 個までに制限されています。このため一般に、幅広いグループ化キーと複雑な集計で多数の列を出力するクエリよりも、対象を絞ったグループ化キーと単純な集計で多数の行を出力するクエリを記述することをおすすめします。次のようなパターンは避けましょう。
SELECT
COUNTIF(field_1 = a_1 AND field_2 = b_1) AS cnt_1,
COUNTIF(field_1 = a_2 AND field_2 = b_2) AS cnt_2
FROM
table
同一のフィールド群を基準にイベントの数をカウントするクエリは、GROUP BY を使ったクエリに書き直しましょう。
SELECT
field_1,
field_2,
COUNT(1) AS cnt
FROM
table
GROUP BY
1, 2
得られた結果は、BigQuery で同じように集計可能です。
配列から列を作成するステップと、作成した列を集計するステップに分かれているクエリは、書き直してひとつにまとめましょう。
SELECT
COUNTIF(a_1) AS cnt_1,
COUNTIF(a_2) AS cnt_2
FROM
(SELECT
1 IN UNNEST(field) AS a_1,
2 IN UNNEST(field) AS a_2,
FROM
table)
上のクエリは次のように書き直すことができます。
SELECT f, COUNT(1) FROM table, UNNEST(field) AS f GROUP BY 1
互いに異なるフィールド群を使ってそれぞれ異なる集計を行うクエリは、複数のより限定的なクエリに分割できます。
SELECT
COUNTIF(field_1 = a_1) AS cnt_a_1,
COUNTIF(field_1 = b_1) AS cnt_b_1,
COUNTIF(field_2 = a_2) AS cnt_a_2,
COUNTIF(field_2 = b_2) AS cnt_b_2,
FROM table
上のクエリは次のように分割可能です。
SELECT
field_1, COUNT(*) AS cnt
FROM table
GROUP BY 1
と
SELECT
field_2, COUNT(*) AS cnt
FROM table
GROUP BY 1
得られた結果を別々のクエリに分割したり、1 つのクエリ内で複数のテーブルを作成して結合したりするほか、スキーマに互換性があれば UNION で結合することも可能です。
結合の意味を理解して最適化する
ベスト プラクティス: クリックまたはコンバージョンをインプレッションに結合するには、INNER JOIN
ではなく LEFT JOIN
を使用する。
すべてのインプレッションがクリックまたはコンバージョンに関連付けられているわけではありません。そのため、クリックまたはコンバージョンをインプレッションに INNER JOIN
した場合、コンバージョンに関連付けられていないクリックまたはインプレッションは結果から除外されます。
複数の最終結果を BigQuery で結合する
ベスト プラクティス: 集約された結果を結合する Ads Data Hub クエリを実行するのではなく、2 つのクエリを別々に作成し、その結果を BigQuery で結合する。
集計要件を満たさない行は結果から除外されます。そのため、十分に集約されていない行と、十分に集約された行が結合された場合、その結果の行は除外されます。また、複数の集計を含むクエリは、Ads Data Hub でのパフォーマンスが低下します。
Ads Data Hub からの複数の集計クエリは、BigQuery で結果を結合できます。一般的なクエリを使用して計算された結果では、最終的に同じスキーマが使用されます。
次のクエリでは、Ads Data Hub の個々の結果(campaign_data_123
と campaign_data_456
)が取得され、BigQuery で結合されます。
SELECT t1.campaign_id, t1.city, t1.X, t2.Y
FROM `campaign_data_123` AS t1
FULL JOIN `campaign_data_456` AS t2
USING (campaign_id, city)
除外された行の概要を使用する
ベスト プラクティス: フィルタされた行の概要をクエリに追加する。
フィルタされた行の概要では、プライバシー チェックによって除外されたデータが集計されます。フィルタされた行のデータが合計され、キャッチオール行に追加されます。フィルタされたデータはこれ以上分析できませんが、結果から除外されたデータの量の概要を把握することができます。
ゼロに設定されたユーザー ID を考慮に入れる
ベスト プラクティス: 結果でゼロに設定されたユーザー ID を考慮に入れる。
エンドユーザーの ID が 0 に設定される理由には、広告のカスタマイズのオプトアウトや、規制によるものなどがあります。そのため、複数のユーザーからのデータが 0 の user_id
に関連付けられることになります。
合計インプレッション数や合計クリック数などのデータの合計を把握するには、そのようなイベントをデータに含めますが、ユーザーに関する分析情報を得るには有用ではないため、そのような分析を行う際は除外する必要があります。
このデータを結果から除外するには、WHERE user_id != "0"
をクエリに追加します。
パフォーマンス
再集計を避ける
ベスト プラクティス: ユーザー間での複数の集計レイヤは避ける。
複数の GROUP BY
が含まれるクエリやネストされた集計など、すでに集計された結果を組み合わせるクエリの場合は、処理するためにリソースがさらに必要になります。
多くの場合、複数の集計レイヤを使用するクエリを分割することで、パフォーマンスを改善できます。その場合、処理中に行をイベント単位またはユーザー単位で保持してから、単一の集計と組み合わせる必要があります。
次のようなパターンは避けてください。
SELECT SUM(count)
FROM
(SELECT campaign_id, COUNT(0) AS count FROM ... GROUP BY 1)
複数の集計レイヤを使用するクエリを、1 つの集計レイヤを使用するように書き換える必要があります。
(SELECT ... GROUP BY ... )
JOIN USING (...)
(SELECT ... GROUP BY ... )
簡単に分割できるクエリは分割し、BigQuery で結果を結合するとよいでしょう。
BigQuery 向けに最適化する
通常、処理量の少ないクエリの方がパフォーマンスが高くなります。クエリのパフォーマンスを評価する場合、必要な処理量は次のようなさまざまな要因によって異なります。
- 入力データとデータソース(I/O): クエリで何バイト読み込むか。
- ノード間の通信(シャッフル): クエリから次の段階に何バイト転送するか。
- コンピューティング: クエリにはどのくらいの CPU 作業が必要か。
- 出力(実体化): クエリは何バイト書き込むか。
- クエリのアンチパターン: クエリは SQL のベスト プラクティスに従っているか。
クエリの実行がサービスレベル契約を満たしていない場合、またはリソースの枯渇やタイムアウトが原因でエラーが発生した場合は、次のことを検討してください。
- 再計算する代わりに以前のクエリの結果を使用する。たとえば、週ごとの合計は、BigQuery で計算された 1 日ごとの集計クエリの 7 日間分の合計になります。
- クエリを論理サブクエリに分解する(たとえば、複数の結合を複数のクエリに分割する)、または処理中のデータセットを制限する。BigQuery で、個々のジョブの結果を 1 つのデータセットにまとめることで、リソースの枯渇を避けることができます。ただし、クエリの速度が低下する可能性があります。
- BigQuery でリソース超過エラーが発生している場合は、一時テーブルを使用して、クエリを複数の BigQuery クエリに分割してみる。
- 1 回のクエリで参照するテーブル数を減らす。参照するテーブル数が多いと、メモリ使用量が多くなり、クエリが失敗する可能性があります。
- 結合するユーザー テーブルの数を減らすようにクエリを書き換える。
- 同じテーブルを再度結合しないようにクエリを書き換える。
クエリ アドバイザー
有効な SQL であっても、過度のフィルタ処理を引き起こす可能性がある場合は、クエリ作成中にクエリ アドバイザーによる具体的なアドバイスが提供され、望ましくない結果を避けられるようになっています。
次のような場合に、アドバイスが提供されます。
- 集計されたサブクエリの結合
- 異なっている可能性のあるユーザーとの未集計のデータの結合
- 再帰的に定義された一時テーブル
クエリ アドバイザーを使用するには:
- 管理画面。アドバイスは、クエリエディタ内のクエリテキストの上に表示されます。
- API。
customers.analysisQueries.validate
メソッドを使用します。