권장사항

이 페이지에서는 Google Ads 스크립트로 개발하기 위한 다양한 권장사항을 다룹니다.

선택기

Selector로 필터링

가능하면 필터를 사용하여 필요한 항목만 요청합니다. 적절한 필터를 적용하면 다음과 같은 이점이 있습니다.

  • 코드가 훨씬 간단하고 쉬워 이해하기 쉽습니다.
  • 스크립트가 훨씬 빠르게 실행됩니다.

다음 코드 스니펫을 비교해 보세요.

코딩 방식 코드 스니펫
선택기를 사용하여 필터링 (권장)
var keywords = AdsApp.keywords()
    .withCondition('Clicks > 10')
    .forDateRange('LAST_MONTH')
    .get();
while (keywords.hasNext()) {
  var keyword = keywords.next();
  // Do work here.
}
코드에서 필터링(권장하지 않음)
var keywords = AdsApp.keywords().get();

while (keywords.hasNext()) {
  var keyword = keywords.next();
  var stats = keyword.getStatsFor(
      'LAST_MONTH');
  if (stats.getClicks() > 10) {
    // Do work here.
  }
}

두 번째 접근 방식은 목록에 필터를 적용하기 위해 계정의 모든 키워드 목록을 가져오려고 시도하므로 권장하지 않습니다.

캠페인 계층구조의 탐색 방지

특정 수준에서 항목을 검색하려면 전체 캠페인 계층 구조를 탐색하는 대신 해당 수준에서 컬렉션 메서드를 사용하세요. 이렇게 하면 더 간단해질 뿐만 아니라 성능도 훨씬 향상됩니다. 시스템에서 모든 캠페인과 광고 그룹을 불필요하게 읽지 않아도 되기 때문입니다.

계정의 모든 광고를 가져오는 다음 코드 스니펫을 비교해 보세요.

코딩 접근 방식 코드 스니펫
적절한 수집 방법 사용(권장)

var ads = AdsApp.ads();

계층 구조 탐색(권장되지 않음)
var campaigns = AdsApp.campaigns().get();
while (campaigns.hasNext()) {
  var adGroups = campaigns.next().
      adGroups().get();
  while (adGroups.hasNext()) {
    var ads = adGroups.next().ads().get();
    // Do your work here.
  }
}

두 번째 접근 방식은 광고만 필요한 반면 객체의 전체 계층 구조(캠페인, 광고 그룹)를 가져오려고 시도하므로 권장하지 않습니다.

특정 상위 접근자 메서드 사용

가져온 객체의 상위 항목을 가져와야 하는 경우가 있습니다. 이 경우 전체 계층 구조를 가져오는 대신 제공된 접근자 메서드를 사용해야 합니다.

지난달 클릭수가 50회를 초과하는 텍스트 광고가 있는 광고 그룹을 검색하는 다음 코드 스니펫을 비교해 보세요.

코딩 접근 방식 코드 스니펫
적절한 상위 액세서리 메서드 사용(권장)
var ads = AdsApp.ads()
    .withCondition('Clicks > 50')
    .forDateRange('LAST_MONTH')
    .get();

while (ads.hasNext()) {
  var ad = ads.next();
  var adGroup = ad.getAdGroup();
  var campaign = ad.getCampaign();
  // Store (campaign, adGroup) to an array.
}
계층 구조 탐색(권장되지 않음)
var campaigns = AdsApp.campaigns().get();
while (campaigns.hasNext()) {
  var adGroups = campaigns.next()
      .adGroups()
      .get();
  while (adGroups.hasNext()) {
    var ads = adGroups.ads()
       .withCondition('Clicks > 50')
       .forDateRange('LAST_MONTH')
       .get();
    if (ads.totalNumEntities() > 0) {
      // Store (campaign, adGroup) to an array.
    }
  }
}

두 번째 접근 방식은 계정의 전체 캠페인 및 광고 그룹 계층 구조를 가져오므로 권장하지 않습니다. 광고 세트와 연결된 캠페인 및 광고 그룹의 하위 집합만 있으면 됩니다. 첫 번째 접근 방식은 관련된 광고 컬렉션만 가져오도록 자체적으로 제한하고 적절한 메서드를 사용하여 상위 객체에 액세스합니다.

특정 상위 필터 사용

특정 캠페인 또는 광고 그룹 내 항목에 액세스하려면 계층 구조를 가져와서 탐색하는 대신 선택기에 특정 필터를 사용하세요.

지난달에 클릭수가 50회 이상인 지정된 캠페인 및 광고 그룹 내 텍스트 광고 목록을 가져오는 다음 코드 스니펫을 비교해 보세요.

코딩 접근 방식 코드 스니펫
적절한 상위 수준 필터 사용(권장)
var ads = AdsApp.ads()
    .withCondition('CampaignName = "Campaign 1"')
    .withCondition('AdGroupName = "AdGroup 1"')
    .withCondition('Clicks > 50')
    .forDateRange('LAST_MONTH')
    .get();

while (ads.hasNext()) {
  var ad = ads.next();
  var adGroup = ad.getAdGroup();
  var campaign = ad.getCampaign();
  // Store (campaign, adGroup, ad) to
  // an array.
}
계층 구조 탐색(권장되지 않음)
var campaigns = AdsApp.campaigns()
    .withCondition('Name = "Campaign 1"')
    .get();

while (campaigns.hasNext()) {
  var adGroups = campaigns.next()
      .adGroups()
      .withCondition('Name = "AdGroup 1"')
      .get();
  while (adGroups.hasNext()) {
    var ads = adGroups.ads()
       .withCondition('Clicks > 50')
       .forDateRange('LAST_MONTH')
       .get();
    while (ads.hasNext()) {
      var ad = ads.next();
      // Store (campaign, adGroup, ad) to
      // an array.
    }
  }
}

두 번째 접근 방식은 계정의 캠페인 및 광고 그룹 계층 구조에서 반복 실행되기 때문에 권장되지 않습니다. 반면 선택한 광고 집합과 상위 캠페인 및 광고 그룹만 있으면 됩니다. 첫 번째 접근 방식은 선택기에 상위 항목에 대한 특정 필터를 적용하여 반복을 광고 목록으로 제한합니다.

가능한 경우 ID를 사용하여 필터링하세요.

항목을 필터링할 때는 다른 필드 대신 ID로 항목을 필터링하는 것이 좋습니다.

캠페인을 선택하는 다음 코드 스니펫을 살펴보세요.

코딩 방식 코드 스니펫
ID로 필터링 (권장)
var campaign = AdsApp.campaigns()
    .withIds([12345])
    .get()
    .next();
이름으로 필터링(최적화되지 않음)
var campaign = AdsApp.campaigns()
    .withCondition('Name="foo"')
    .get()
    .next();

두 번째 접근 방식은 ID가 아닌 필드로 필터링하므로 최적화되지 않습니다.

가능한 경우 부모 ID로 필터링

항목을 선택할 때는 가능하면 상위 ID로 필터링하세요. 이렇게 하면 결과를 필터링할 때 서버에서 가져오는 항목 목록을 제한하여 쿼리 속도가 빨라집니다.

ID로 AdGroup을 가져오는 다음 코드 스니펫을 살펴보세요. 상위 캠페인 ID가 알려져 있다고 가정합니다.

코딩 방식 코드 스니펫
캠페인 및 광고그룹 ID별로 필터링(권장)
var adGroup = AdsApp.adGroups()
    .withIds([12345])
    .withCondition('CampaignId="54678"')
    .get()
    .next();
광고 그룹 ID만으로 필터링(최적화되지 않음)
var adGroup = AdsApp.adGroups()
    .withIds([12345])
    .get()
    .next();

두 코드 스니펫 모두 동일한 결과를 제공하지만, 코드 스니펫 1에서 상위 ID (CampaignId="54678")를 사용하여 추가 필터링을 수행하면 결과를 필터링할 때 서버에서 반복해야 하는 항목 목록을 제한하여 코드의 효율성을 높일 수 있습니다.

필터링 조건이 너무 많은 경우 라벨 사용

필터링 조건이 너무 많으면 처리하는 항목에 대한 라벨을 만들고 이 라벨을 사용하여 항목을 필터링하는 것이 좋습니다.

다음 코드 스니펫은 이름별로 캠페인 목록을 가져옵니다.

코딩 접근 방식 코드 스니펫
라벨 사용(권장)
var label = AdsApp.labels()
    .withCondition('Name = "My Label"')
    .get()
    .next();
var campaigns = label.campaigns.get();
while (campaigns.hasNext()) {
  var campaign = campaigns.next();
  // Do more work
}
복잡한 선택기 빌드(권장하지 않음)
var campaignNames = [‘foo’, ‘bar’, ‘baz’];

for (var i = 0; i < campaignNames.length; i++) {
  campaignNames[i] = '"' + campaignNames[i] + '"';
}

var campaigns = AdsApp.campaigns
    .withCondition('CampaignName in [' + campaignNames.join(',') + ']')
    .get();

while (campaigns.hasNext()) {
  var campaign = campaigns.next();
  // Do more work.
}

두 코드 스니펫 모두 비슷한 수준의 성능을 제공하지만 두 번째 접근 방식에서는 선택기의 조건 수가 증가함에 따라 더 복잡한 코드를 생성하는 경향이 있습니다. 또한 새 항목을 포함하도록 스크립트를 수정하는 것보다 새 항목에 라벨을 적용하는 것이 더 쉽습니다.

IN 절의 조건 수 제한

스크립트를 실행할 때 일반적인 사용 사례는 항목 목록에 관한 보고서를 실행하는 것입니다. 개발자는 일반적으로 IN 절을 사용하여 항목 ID를 필터링하는 매우 긴 AWQL 쿼리를 작성하여 이를 수행합니다. 이 방법은 항목 수가 제한된 경우에 효과적입니다. 그러나 쿼리 길이가 늘어남에 따라 다음 두 가지 이유로 스크립트 성능이 저하됩니다.

  • 쿼리가 길수록 파싱하는 데 시간이 더 오래 걸립니다.
  • IN 절에 추가하는 각 ID는 평가할 추가 조건이므로 시간이 더 오래 걸립니다.

이러한 조건에서는 항목에 라벨을 적용한 다음 LabelId로 필터링하는 것이 좋습니다.

코딩 접근 방식 코드 스니펫
라벨 적용 및 labelID로 필터링 (권장)
// The label applied to the entity is "Report Entities"
var label = AdsApp.labels()
    .withCondition('LabelName contains "Report Entities"')
    .get()
    .next();

var report = AdsApp.report('SELECT AdGroupId, Id, Clicks, ' +
    'Impressions, Cost FROM KEYWORDS_PERFORMANCE_REPORT ' +
    'WHERE LabelId = "' + label.getId() + '"');
IN 절을 사용하여 긴 쿼리 빌드(권장하지 않음)
var report = AdsApp.report('SELECT AdGroupId, Id, Clicks, ' +
    'Impressions, Cost FROM KEYWORDS_PERFORMANCE_REPORT WHERE ' +
    'AdGroupId IN (123, 456) and Id in (123,345, 456…)');

계정 업데이트

일괄 변경 수행

Google Ads 항목을 변경해도 Google Ads 스크립트는 변경사항을 즉시 실행하지 않습니다. 대신 여러 변경사항을 배치로 결합하여 여러 변경사항을 실행하는 단일 요청을 실행할 수 있도록 합니다. 이 접근 방식을 사용하면 스크립트가 더 빠르게 실행되고 Google Ads 서버의 부하가 줄어듭니다. 하지만 Google Ads 스크립트가 일괄 작업을 자주 플러시하도록 강제하여 스크립트가 느리게 실행되는 코드 패턴이 있습니다.

키워드 목록의 입찰가를 업데이트하는 다음 스크립트를 살펴보세요.

코딩 접근 방식 코드 스니펫
업데이트된 요소 추적하기 (권장)
var keywords = AdsApp.keywords()
    .withCondition('Clicks > 50')
    .withCondition('CampaignName = "Campaign 1"')
    .withCondition('AdGroupName = "AdGroup 1"')
    .forDateRange('LAST_MONTH')
    .get();

var list = [];
while (keywords.hasNext()) {
  var keyword = keywords.next();
  keyword.bidding().setCpc(1.5);
  list.push(keyword);
}

for (var i = 0; i < list.length; i++) {
  var keyword = list[i];
  Logger.log('%s, %s', keyword.getText(),
      keyword.bidding().getCpc());
}
짧은 루프에서 업데이트된 요소 검색(권장하지 않음)
var keywords = AdsApp.keywords()
    .withCondition('Clicks > 50')
    .withCondition('CampaignName = "Campaign 1"')
    .withCondition('AdGroupName = "AdGroup 1"')
    .forDateRange('LAST_MONTH')
    .get();

while (keywords.hasNext()) {
  var keyword = keywords.next();
  keyword.bidding().setCpc(1.5);
  Logger.log('%s, %s', keyword.getText(),
      keyword.bidding().getCpc());
}

keyword.bidding().getCpc() 호출은 Google Ads 스크립트가 setCpc() 작업을 플러시하고 한 번에 하나의 작업만 실행하도록 강제하므로 두 번째 접근 방식은 권장되지 않습니다. 첫 번째 접근 방식은 두 번째 접근 방식과 유사하지만 getCpc() 호출이 setCpc()가 호출되는 루프와 별도의 루프에서 실행되므로 일괄 처리를 지원하는 추가 이점이 있습니다.

가능한 경우 빌더 사용

Google Ads 스크립트는 새 객체를 만드는 두 가지 방법인 생성자와 생성 메서드를 지원합니다. 빌더는 API 호출에서 생성된 객체에 액세스할 수 있으므로 생성 메서드보다 유연합니다.

다음 코드 스니펫을 살펴보세요.

코딩 접근 방식 코드 스니펫
빌더 사용(권장)
var operation = adGroup.newKeywordBuilder()
    .withText('shoes')
    .build();
var keyword = operation.getResult();
생성 메서드 사용(권장하지 않음)
adGroup.createKeyword('shoes');
var keyword = adGroup.keywords()
    .withCondition('KeywordText="shoes"')
    .get()
    .next();

두 번째 접근 방식은 키워드 검색과 관련된 추가 선택 연산으로 인해 선호되지 않습니다. 또한 만들기 메서드도 지원 중단됩니다.

그러나 빌더를 잘못 사용하면 Google Ads 스크립트가 작업을 일괄 처리하지 못할 수 있습니다.

키워드 목록을 만들고 새로 만든 키워드의 ID를 출력하는 다음 코드 스니펫을 살펴보세요.

코딩 접근 방식 코드 스니펫
업데이트된 요소 추적하기 (권장)
var keywords = [‘foo’, ‘bar’, ‘baz’];

var list = [];
for (var i = 0; i < keywords.length; i++) {
  var operation = adGroup.newKeywordBuilder()
      .withText(keywords[i])
      .build();
  list.push(operation);
}

for (var i = 0; i < list.length; i++) {
  var operation = list[i];
  var result = operation.getResult();
  Logger.log('%s %s', result.getId(),
      result.getText());
}
짧은 루프에서 업데이트된 요소 검색(권장하지 않음)
var keywords = [‘foo’, ‘bar’, ‘baz’];

for (var i = 0; i < keywords.length; i++) {
  var operation = adGroup.newKeywordBuilder()
      .withText(keywords[i])
      .build();
  var result = operation.getResult();
  Logger.log('%s %s', result.getId(),
      result.getText());
}

두 번째 접근 방식은 작업을 만드는 동일한 루프 내에서 operation.getResult()를 호출하므로 Google Ads 스크립트가 한 번에 하나의 작업을 실행하도록 강제하므로 권장되지 않습니다. 첫 번째 접근 방식은 유사하지만 생성된 루프와 다른 루프에서operation.getResult()를 호출하므로 일괄 처리를 허용합니다.

대규모 업데이트의 경우 일괄 업로드 사용 고려

개발자가 수행하는 일반적인 작업은 보고서를 실행하고 현재 실적 값을 기반으로 항목 속성(예: 키워드 입찰가)을 업데이트하는 것입니다. 많은 수의 항목을 업데이트해야 하는 경우 일괄 업로드를 사용하면 성능이 향상됩니다. 예를 들어 지난 한 달 동안 TopImpressionPercentage > 0.4가 가장 높은 키워드의 MaxCpc를 늘리는 다음 스크립트를 생각해 보세요.

코딩 접근 방식 코드 스니펫
일괄 업로드 사용(권장)

var report = AdsApp.report(
  'SELECT AdGroupId, Id, CpcBid FROM KEYWORDS_PERFORMANCE_REPORT ' +
  'WHERE TopImpressionPercentage > 0.4 DURING LAST_MONTH');

var upload = AdsApp.bulkUploads().newCsvUpload([
  report.getColumnHeader('AdGroupId').getBulkUploadColumnName(),
  report.getColumnHeader('Id').getBulkUploadColumnName(),
  report.getColumnHeader('CpcBid').getBulkUploadColumnName()]);
upload.forCampaignManagement();

var reportRows = report.rows();
while (reportRows.hasNext()) {
  var row = reportRows.next();
  row['CpcBid'] = row['CpcBid'] + 0.02;
  upload.append(row.formatForUpload());
}

upload.apply();
ID별로 키워드 선택 및 업데이트(최적화도가 낮음)
var reportRows = AdsApp.report('SELECT AdGroupId, Id, CpcBid FROM ' +
    'KEYWORDS_PERFORMANCE_REPORT WHERE TopImpressionPercentage > 0.4 ' +
    ' DURING LAST_MONTH')
    .rows();

var map = {
};

while (reportRows.hasNext()) {
  var row = reportRows.next();
  var adGroupId = row['AdGroupId'];
  var id = row['Id'];

  if (map[adGroupId] == null) {
    map[adGroupId] = [];
  }
  map[adGroupId].push([adGroupId, id]);
}

for (var key in map) {
  var keywords = AdsApp.keywords()
      .withCondition('AdGroupId="' + key + '"')
      .withIds(map[key])
      .get();

  while (keywords.hasNext()) {
    var keyword = keywords.next();
    keyword.bidding().setCpc(keyword.bidding().getCpc() + 0.02);
  }
}

두 번째 접근 방식이 꽤 좋은 성능을 제공하지만, 이 경우에는 첫 번째 접근 방식이 선호되므로

  • Google Ads 스크립트에는 단일 실행에서 검색하거나 업데이트할 수 있는 객체 수에 제한이 있으며 두 번째 접근 방식의 선택 및 업데이트 작업은 이 제한에 포함됩니다.

  • 일괄 업로드의 경우 업데이트할 수 있는 항목 수와 전체 실행 시간 모두에 더 높은 한도가 적용됩니다.

캠페인별로 일괄 업로드 그룹화

일괄 업로드를 만들 때는 상위 캠페인별로 작업을 그룹화하는 것이 좋습니다. 이렇게 하면 효율성이 높아지고 충돌하는 변경사항/동시 실행 오류가 발생할 가능성이 줄어듭니다.

동시에 실행되는 두 개의 일괄 업로드 작업을 고려해 보세요. 하나는 광고 그룹의 광고를 일시중지하고, 다른 하나는 키워드 입찰가를 조정합니다. 작업이 관련이 없더라도 동일한 광고그룹(또는 동일한 캠페인에 속한 두 개의 서로 다른 광고그룹)의 항목에 작업이 적용될 수 있습니다. 이 경우 시스템에서 상위 항목 (공유 광고그룹 또는 캠페인)을 잠그기 때문에 일괄 업로드 작업이 서로 차단하게 됩니다.

Google Ads 스크립트는 단일 일괄 업로드 작업 내에서 실행을 최적화할 수 있으므로 가장 간단한 방법은 계정당 한 번에 하나의 일괄 업로드 작업만 실행하는 것입니다. 계정당 일괄 업로드를 두 번 이상 실행하려는 경우 최적의 실적을 위해 일괄 업로드가 상호 배타적인 캠페인 목록(및 하위 항목)에서 실행되는지 확인하세요.

보고

통계 가져오기에 보고서 사용

대량의 항목과 해당 통계를 검색하려면 표준 AdsApp 메서드 대신 보고서를 사용하는 것이 좋습니다. 보고서를 사용하는 것이 더 좋은 이유는 다음과 같습니다.

  • 보고서를 사용하면 대규모 쿼리의 성능을 개선할 수 있습니다.
  • 보고서는 일반 가져오기 할당량에 도달하지 않습니다.

지난달에 클릭수가 50회 이상 발생한 모든 키워드의 클릭수, 노출수, 비용, 텍스트를 가져오는 다음 코드 스니펫을 비교하세요.

코딩 접근 방식 코드 스니펫
보고서 사용(권장)
  report = AdsApp.search(
      'SELECT ' +
      '   ad_group_criterion.keyword.text, ' +
      '   metrics.clicks, ' +
      '   metrics.cost_micros, ' +
      '   metrics.impressions ' +
      'FROM ' +
      '   keyword_view ' +
      'WHERE ' +
      '   segments.date DURING LAST_MONTH ' +
      '   AND metrics.clicks > 50');
  while (report.hasNext()) {
    var row = report.next();
    Logger.log('Keyword: %s Impressions: %s ' +
        'Clicks: %s Cost: %s',
        row.adGroupCriterion.keyword.text,
        row.metrics.impressions,
        row.metrics.clicks,
        row.metrics.cost);
  }
AdsApp 반복자 사용(권장하지 않음)
var keywords = AdsApp.keywords()
    .withCondition('metrics.clicks > 50')
    .forDateRange('LAST_MONTH')
    .get();
while (keywords.hasNext()) {
  var keyword = keywords.next();
  var stats = keyword.getStatsFor('LAST_MONTH');
  Logger.log('Keyword: %s Impressions: %s ' +
      'Clicks: %s Cost: %s',
      keyword.getText(),
      stats.getImpressions(),
      stats.getClicks(),
      stats.getCost());
}

두 번째 접근 방식은 키워드를 반복하고 한 번에 하나의 항목씩 통계를 검색하므로 선호되지 않습니다. 이 경우 보고서는 단일 호출에서 모든 데이터를 가져와 필요에 따라 스트리밍하므로 더 빠르게 실행됩니다. 또한 두 번째 접근 방식에서 검색된 키워드는 get() 호출을 사용하여 검색된 항목 수에 대한 스크립트의 할당량에 포함됩니다.

신고 대신 검색 사용

보고서 메서드는 이전 인프라용으로 빌드되었으며 GAQL을 사용하는 경우에도 결과를 플랫 형식으로 출력합니다. 즉, 이전 스타일과 일치하도록 쿼리 결과를 변환해야 하며, 이는 일부 필드에서 지원되지 않으며 각 호출에 오버헤드를 추가합니다.

대신 검색을 사용하여 새 Google Ads API 보고의 모든 기능을 활용하는 것이 좋습니다.

AWQL보다 GAQL을 선호합니다.

AWQL은 보고서 쿼리 및 withCondition 호출에서 계속 지원되지만, 실제 AWQL과 완전히 호환되지 않는 변환 레이어를 통해 실행됩니다. 쿼리를 완전히 제어하려면 GAQL을 사용하고 있는지 확인하세요.

기존 AWQL 쿼리를 변환하려면 쿼리 이전 도구를 사용하세요.

필요한 것보다 더 많은 행을 선택하지 않음

보고서 (및 선택기)의 실행 속도는 반복 여부와 관계없이 보고서에 반환되는 총 행 수를 기반으로 합니다. 즉, 항상 특정 필터를 사용하여 사용 사례에 맞게 결과 집합을 최소화해야 합니다.

예를 들어 특정 범위를 벗어난 입찰가가 있는 광고 그룹을 찾으려는 경우를 가정해 보겠습니다. 모든 광고 그룹을 가져와 관심 없는 광고 그룹을 무시하는 것보다 하한 기준점 미만의 입찰가에 관한 검색어와 상한 기준점 초과의 입찰가에 관한 검색어를 각각 두 번 실행하는 것이 더 빠릅니다.

코딩 접근 방식 코드 스니펫
두 개의 쿼리 사용(권장)
var adGroups = []
var report = AdsApp.search(
    'SELECT ad_group.name, ad_group.cpc_bid_micros' +
    ' FROM ad_group WHERE ad_group.cpc_bid_micros < 1000000');

while (report.hasNext()) {
  var row = report.next();
  adGroups.push(row.adGroup);
}
var report = AdsApp.search(
    'SELECT ad_group.name, ad_group.cpc_bid_micros' +
    ' FROM ad_group WHERE ad_group.cpc_bid_micros > 2000000');

while (report.hasNext()) {
  var row = report.next();
  adGroups.push(row.adGroup);
}
일반 검색어에서 필터링하기(권장하지 않음)
var adGroups = []
var report = AdsApp.search(
    'SELECT ad_group.name, ad_group.cpc_bid_micros' +
    ' FROM ad_group');

while (report.hasNext()) {
  var row = report.next();
  var cpcBidMicros = row.adGroup.cpcBidMicros;
  if (cpcBidMicros < 1000000 || cpcBidMicros > 2000000) {
    adGroups.push(row.adGroup);
  }
}

Ad Manager(MCC) 스크립트

연속 실행보다 executeInParallel을 선호합니다.

관리자 계정의 스크립트를 작성할 때는 가능하면 직렬 실행 대신 executeInParallel()를 사용하세요. executeInParallel()를 사용하면 스크립트의 처리 시간이 최대 1시간으로 늘어나고 처리되는 계정당 최대 30분(직렬 실행의 경우 총 30분)이 소요됩니다. 자세한 내용은 한도 페이지를 참고하세요.

스프레드시트

스프레드시트를 업데이트할 때 일괄 작업 사용

스프레드시트를 업데이트할 때는 한 번에 하나의 셀을 업데이트하는 메서드보다 일괄 작업 메서드(예: getRange())를 사용해 보세요.

스프레드시트에서 프랙탈 패턴을 생성하는 다음 코드 스니펫을 고려해 보세요.

코딩 접근 방식 코드 스니펫
단일 호출로 여러 셀 범위 업데이트(권장)
var colors = new Array(100);
for (var y = 0; y < 100; y++) {
  xcoord = xmin;
  colors[y] = new Array(100);
  for (var x = 0; x < 100; x++) {
    colors[y][x] = getColor_(xcoord, ycoord);
    xcoord += xincrement;
  }
  ycoord -= yincrement;
}
sheet.getRange(1, 1, 100, 100).setBackgroundColors(colors);
한 번에 하나의 셀 업데이트(권장하지 않음)
var cell = sheet.getRange('a1');
for (var y = 0; y < 100; y++) {
  xcoord = xmin;
  for (var x = 0; x < 100; x++) {
    var c = getColor_(xcoord, ycoord);
    cell.offset(y, x).setBackgroundColor(c);
    xcoord += xincrement;
  }
  ycoord -= yincrement;
  SpreadsheetApp.flush();
}

Google Sheets는 값을 캐시하여 두 번째 코드 스니펫을 최적화하려고 하지만 API 호출 수가 많아 첫 번째 스니펫에 비해 성능이 좋지 않습니다.