有效管理資料

許多 Google Ads 應用程式的核心功能,就是擷取帳戶資料,以利於進行資料分析、客戶查詢和政策遵循檢查等用途。擷取資料時,請盡量減少使用量,以免 Google 伺服器過載,或導致頻率受限。詳情請參閱速率限制保持聯絡電子郵件地址更新的指南。

瞭解 Google 的報表資源用量政策

為確保伺服器的穩定性,Google Ads API 會節流耗用過多 API 資源的 GoogleAdsService.SearchGoogleAdsService.SearchStream 查詢模式。如果特定查詢模式遭到限流,其他服務、方法和查詢模式仍會繼續運作,不會受到影響。系統會針對調節要求擲回以下錯誤:

API 版本 錯誤代碼
<= v17 QuotaError.RESOURCE_EXHAUSTED
>= v18 QuotaError.EXCESSIVE_SHORT_TERM_QUERY_RESOURCE_CONSUMPTIONQuotaError.EXCESSIVE_LONG_TERM_QUERY_RESOURCE_CONSUMPTION (視資源使用率高峰期長短而定)。

為了協助您找出並監控成本較高的報表,我們也會針對個別報表傳回成本指標。

方法 費用欄位
GoogleAdsService.Search SearchGoogleAdsResponse.query_resource_consumption
GoogleAdsService.SearchStream SearchGoogleAdsStreamResponse.query_resource_consumption

這些欄位傳回的費用指標取決於多項因素,例如:

  • 帳戶規模
  • 報表中擷取的檢視畫面和資料欄
  • Google Ads API 伺服器的負載。

為協助您追蹤耗用資源的查詢,我們會發布初始的匯總統計資料,說明我們在伺服器上看到的各種查詢模式的資源用量。我們會定期發布更新的數據,協助您微調查詢。

時間範圍 平均值 (第 50 個百分位數)。 P70 (中高) P95 (極高)
短期 (5 分鐘) 6000 30000 1800000
長期 (24 小時)。 16000 90000 8400000

舉例來說,假設您執行的查詢模式如下,每份報表會消耗 600 個資源單位。

SELECT campaign.id, campaign.name, metrics.cost_micros FROM campaign WHERE
    segments.date = "YYYY-MM-DD"

您可以修改查詢,為 segments.date 篩選器替換不同的值,為多個客戶帳戶執行這項查詢,並針對多個日期進行查詢。下表顯示您可以在特定時間範圍內執行的報表數量,讓資源用量符合各種資源用量分層。

時間範圍 平均值 中高 非常高
短期 (5 分鐘) 10 50 3000
長期 (24 小時)。 26 150 14000

在 5 分鐘內執行這個查詢模式 10 次,會被視為平均用量,但在 5 分鐘內執行 3000 份報表,則會被視為高用量。

您可以透過幾種策略來改善報表的資源用量。本指南的其餘部分會說明其中部分策略。

快取資料

您應在本機資料庫中快取從 API 伺服器擷取的實體詳細資料,而非每次需要資料時都呼叫伺服器,特別是經常存取或不常變更的實體。請盡可能使用 change-eventchange-status,偵測自上次同步結果後,哪些物件發生變更。

調整報表執行頻率

Google Ads 已發布指南,說明資料的新鮮度和更新頻率。您應根據這項指南決定擷取報表的頻率。

如果您需要定期更新帳戶,建議您將這類帳戶的數量限制在少數幾個,例如只保留前二十個 Google Ads 帳戶。其餘資料則可以較低的頻率更新,例如每天一次或兩次。

最佳化報表大小

應用程式應擷取大量資料,而非執行大量小型報表。影響這項選擇的因素之一是帳戶限制

舉例來說,請考慮下列程式碼,該程式碼會擷取特定廣告群組的統計資料,並更新統計資料資料庫表格:

  List<long> adGroupIds = FetchAdGroupIdsFromLocalDatabase();

  foreach (long adGroupId in adGroupIds)
  {
    string query = "SELECT ad_group.id, ad_group.name, metrics.clicks, " +
        "metrics.cost_micros, metrics.impressions, segments.date FROM " +
        "ad_group WHERE segments.date DURING LAST_7_DAYS AND " +
        "ad_group.id = ${adGroupId}";
    List<GoogleAdsRow> rows = RunGoogleAdsReport(customerId, query);
    InsertRowsIntoStatsTable(adGroupId, rows);
  }

這段程式碼適用於小型測試帳戶。不過,Google Ads 最多可支援每個廣告活動 20,000 個廣告群組,以及每個帳戶 10,000 個廣告活動。因此,如果這段程式碼針對大型 Google Ads 帳戶執行,可能會造成 Google Ads API 伺服器超載,導致速率限制和節流。

建議您執行單一報表,並在本機處理。這裡會示範使用記憶體地圖的這類方法。

  Hashset<long> adGroupIds = FetchAdGroupIdsFromLocalDatabase();

  string query = "SELECT ad_group.id, ad_group.name, metrics.clicks, " +
      "metrics.cost_micros, metrics.impressions, segments.date FROM " +
      "ad_group WHERE segments.date DURING LAST_7_DAYS";
  List<GoogleAdsRow> rows = RunGoogleAdsReport(customer_id, query);

  var memoryMap = new Dictionary<long, List<GoogleAdsRow>>();
  for each (GoogleAdsRow row in rows)
  {
    var adGroupId = row.AdGroup.Id;

    if (adGroupIds.Contains(adGroupId))
    {
      CheckAndAddRowIntoMemoryMap(row, adGroupId, memoryMap);
    }
  }
  foreach (long adGroupId in memoryMap.Keys())
  {
    InsertRowsIntoStatsTable(adGroupId, rows);
  }

這樣一來,由於執行的報表數量較少,Google Ads API 伺服器的負載也會隨之減少。

如果發現報表太大,無法儲存在記憶體中,您也可以新增 LIMIT 子句,將查詢分割成較小的群組,如下所示:

SELECT
  ad_group.id,
  ad_group.name,
  metrics.clicks,
  metrics.cost_micros,
  metrics.impressions,
  segments.date
FROM ad_group
WHERE segments.date DURING LAST_7_DAYS
  AND ad_group.id IN (id1, id2, ...)
LIMIT 100000

標籤是另一種將實體分組並減少報表查詢數量的方式。詳情請參閱標籤指南

最佳化擷取內容

執行報表時,請留意查詢中包含的資料欄。請參考以下每小時執行一次的例子:

SELECT
  customer.id,
  customer.currency_code,
  campaign.id,
  campaign.name,
  ad_group.id,
  ad_group.name,
  ad_group_criterion.keyword.match_type,
  ad_group_criterion.keyword.text,
  ad_group_criterion.criterion_id,
  ad_group_criterion.quality_info.creative_quality_score,
  ad_group_criterion.system_serving_status,
  ad_group_criterion.negative,
  ad_group_criterion.quality_info.quality_score,
  ad_group_criterion.quality_info.search_predicted_ctr,
  ad_group_criterion.quality_info.post_click_quality_score,
  metrics.historical_landing_page_quality_score,
  metrics.search_click_share,
  metrics.historical_creative_quality_score,
  metrics.clicks,
  metrics.impressions
FROM keyword_view
WHERE segments.date DURING LAST_7_DAYS

只有 metrics.clicksmetrics.impressions 這兩個資料欄可能每小時變更一次。所有其他欄的更新頻率不高,甚至不會更新,因此每小時擷取這些欄的做法非常低效。您可以將這些值儲存在本機資料庫中,並執行變更事件變更狀態報表,每天下載一次或兩次變更。

在某些情況下,您可以套用適當的篩選器,減少下載的資料列數量。

清理未使用的帳戶

如果您的應用程式會管理第三方客戶帳戶,則在開發應用程式時,請務必考量客戶流失率。您應定期清理程序和資料儲存庫,移除不再使用應用程式的客戶帳戶。清理未使用的 Google Ads 帳戶時,請注意下列指南:

  • 撤銷客戶授予應用程式管理其帳戶的授權。
  • 停止對客戶的 Google Ads 帳戶發出 API 呼叫。這項功能特別適用於離線工作,例如 Cron 工作和資料管道,因為這些工作設計為不需使用者介入即可執行。
  • 如果客戶撤銷授權,您的應用程式應妥善處理這種情況,避免向 Google 的 API 伺服器傳送無效的 API 呼叫。
  • 如果客戶已取消 Google Ads 帳戶,您應偵測這項情況,避免向 Google 的 API 伺服器傳送無效的 API 呼叫。
  • 在適當的時間過後,從您的本機資料庫刪除從客戶的 Google Ads 帳戶下載的資料。