بهترین شیوه ها

این صفحه، بهترین شیوه‌های مختلف برای توسعه با اسکریپت‌های گوگل ادز را پوشش می‌دهد.

انتخابگرها

فیلتر با انتخابگرها

در صورت امکان، از فیلترها برای درخواست فقط موجودیت‌های مورد نیاز خود استفاده کنید. اعمال فیلترهای مناسب مزایای زیر را دارد:

  • کد ساده‌تر و قابل فهم‌تر است.
  • اسکریپت خیلی سریعتر اجرا خواهد شد.

تکه کدهای زیر را با هم مقایسه کنید:

رویکرد کدگذاری قطعه کد
فیلتر با استفاده از انتخابگرها (توصیه می‌شود)
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.
  }
}

رویکرد دوم توصیه نمی‌شود زیرا تلاش می‌کند کل سلسله مراتب اشیاء (کمپین‌ها، گروه‌های تبلیغاتی) را در حالی که فقط تبلیغات مورد نیاز هستند، واکشی کند.

از متدهای دسترسی والد خاص استفاده کنید

گاهی اوقات نیاز دارید که موجودیت والد یک شیء بازیابی شده را به دست آورید. در این حالت، باید به جای واکشی کل سلسله مراتب، از یک متد دسترسی ارائه شده استفاده کنید.

قطعه کدهای زیر را که گروه‌های تبلیغاتی دارای تبلیغات متنی با بیش از ۵۰ کلیک در ماه گذشته را بازیابی می‌کنند، مقایسه کنید:

رویکرد کدگذاری قطعه کد
از روش دسترسی والد مناسب استفاده کنید (توصیه می‌شود)
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.
    }
  }
}

رویکرد دوم توصیه نمی‌شود زیرا کل سلسله مراتب کمپین و گروه تبلیغاتی را در حساب شما واکشی می‌کند، در حالی که شما فقط به زیرمجموعه‌ای از کمپین‌ها و گروه‌های تبلیغاتی نیاز دارید که با مجموعه تبلیغات شما مرتبط هستند. رویکرد اول خود را محدود به واکشی فقط مجموعه تبلیغات مرتبط می‌کند و از یک روش مناسب برای دسترسی به اشیاء والد آن استفاده می‌کند.

استفاده از فیلترهای والد خاص

برای دسترسی به موجودیت‌های درون یک کمپین یا گروه تبلیغاتی خاص، به جای واکشی و سپس پیمایش سلسله مراتب، از یک فیلتر خاص در انتخابگر استفاده کنید.

قطعه کدهای زیر را که لیست تبلیغات متنی را در یک کمپین و گروه تبلیغاتی مشخص که ماه گذشته بیش از ۵۰ کلیک داشته است، بازیابی می‌کنند، با هم مقایسه کنید.

رویکرد کدگذاری قطعه کد
از فیلترهای سطح والد مناسب استفاده کنید (توصیه می‌شود)
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.
    }
  }
}

رویکرد دوم توصیه نمی‌شود زیرا در حساب کاربری شما، سلسله مراتب کمپین و گروه تبلیغاتی را تکرار می‌کند، در حالی که شما فقط به مجموعه‌ای منتخب از تبلیغات و کمپین‌ها و گروه‌های تبلیغاتی والد آنها نیاز دارید. رویکرد اول با اعمال یک فیلتر خاص برای موجودیت‌های والد در انتخابگر، تکرار را به لیست تبلیغات محدود می‌کند.

در صورت امکان از شناسه‌ها برای فیلتر کردن استفاده کنید

هنگام فیلتر کردن موجودیت‌ها، ترجیحاً به جای فیلدهای دیگر، موجودیت‌ها را بر اساس شناسه‌هایشان فیلتر کنید.

قطعه کدهای زیر را که یک کمپین را انتخاب می‌کنند در نظر بگیرید.

رویکرد کدگذاری قطعه کد
فیلتر بر اساس شناسه (توصیه می‌شود)
var campaign = AdsApp.campaigns()
    .withIds([12345])
    .get()
    .next();
فیلتر بر اساس نام (کمتر بهینه)
var campaign = AdsApp.campaigns()
    .withCondition('Name="foo"')
    .get()
    .next();

رویکرد دوم بهینه نیست زیرا ما بر اساس یک فیلد غیر ID فیلتر می‌کنیم.

هر زمان که ممکن است، بر اساس شناسه والدین فیلتر کنید

هنگام انتخاب یک موجودیت، در صورت امکان بر اساس شناسه‌های والد فیلتر کنید. این کار با محدود کردن لیست موجودیت‌هایی که هنگام فیلتر کردن نتایج توسط سرورها بازیابی می‌شوند، پرس‌وجوهای شما را سریع‌تر می‌کند.

قطعه کد زیر را در نظر بگیرید که یک AdGroup را با استفاده از شناسه‌اش بازیابی می‌کند. فرض کنید شناسه کمپین والد مشخص است.

رویکرد کدگذاری قطعه کد
فیلتر بر اساس شناسه کمپین و گروه تبلیغاتی (توصیه می‌شود)
var adGroup = AdsApp.adGroups()
    .withIds([12345])
    .withCondition('CampaignId="54678"')
    .get()
    .next();
فیلتر فقط بر اساس شناسه گروه تبلیغاتی (کمتر بهینه)
var adGroup = AdsApp.adGroups()
    .withIds([12345])
    .get()
    .next();

اگرچه هر دو قطعه کد نتایج یکسانی ارائه می‌دهند، فیلتر اضافی در قطعه کد ۱ با استفاده از شناسه والد (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 خود را محدود کنید

هنگام اجرای اسکریپت‌ها، یک مورد استفاده رایج، اجرای گزارش برای لیستی از موجودیت‌ها است. توسعه‌دهندگان معمولاً این کار را با ساخت یک پرس‌وجوی GAQL بسیار طولانی انجام می‌دهند که با استفاده از یک عبارت IN، شناسه‌های موجودیت را فیلتر می‌کند. این رویکرد زمانی که تعداد موجودیت‌ها محدود است، به خوبی کار می‌کند. با این حال، با افزایش طول پرس‌وجو، عملکرد اسکریپت شما به دو دلیل کاهش می‌یابد:

  • یک کوئری طولانی‌تر برای تجزیه و تحلیل به زمان بیشتری نیاز دارد.
  • هر شناسه‌ای که به یک عبارت IN اضافه می‌کنید، یک شرط اضافی برای ارزیابی است و از این رو زمان بیشتری طول می‌کشد.

در چنین شرایطی، ترجیح داده می‌شود که یک برچسب به موجودیت‌ها اعمال شود و سپس بر اساس 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…)');

به‌روزرسانی‌های حساب کاربری

تغییرات دسته‌ای

وقتی در یک موجودیت گوگل ادز تغییراتی ایجاد می‌کنید، اسکریپت‌های گوگل ادز بلافاصله آن تغییر را اجرا نمی‌کنند. در عوض، سعی می‌کند چندین تغییر را در دسته‌هایی ترکیب کند تا بتواند یک درخواست واحد صادر کند که چندین تغییر را انجام می‌دهد. این رویکرد اسکریپت‌های شما را سریع‌تر می‌کند و بار روی سرورهای گوگل ادز را کاهش می‌دهد. با این حال، برخی الگوهای کد وجود دارند که اسکریپت‌های گوگل ادز را مجبور می‌کنند تا دسته عملیات خود را مرتباً پاک کنند، در نتیجه باعث می‌شوند اسکریپت شما به کندی اجرا شود.

اسکریپت زیر را در نظر بگیرید که پیشنهادات قیمت لیستی از کلمات کلیدی را به‌روزرسانی می‌کند.

رویکرد کدگذاری قطعه کد
پیگیری عناصر به‌روز شده (توصیه می‌شود)
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() اسکریپت‌های گوگل ادز را مجبور می‌کند تا عملیات setCpc() را پاک کرده و فقط یک عملیات را در هر زمان اجرا کنند. رویکرد اول، اگرچه مشابه رویکرد دوم است، اما مزیت اضافه پشتیبانی از دسته‌بندی را دارد زیرا فراخوانی getCpc() در یک حلقه جداگانه از حلقه‌ای که setCpc() در آن فراخوانی می‌شود، انجام می‌شود.

در صورت امکان از سازندگان استفاده کنید

اسکریپت‌های گوگل ادز از دو روش برای ایجاد اشیاء جدید پشتیبانی می‌کنند - سازندگان و روش‌های ایجاد. سازندگان نسبت به روش‌های ایجاد انعطاف‌پذیرتر هستند، زیرا به شما امکان دسترسی به شیء ایجاد شده از طریق فراخوانی API را می‌دهند.

قطعه کدهای زیر را در نظر بگیرید:

رویکرد کدگذاری قطعه کد
استفاده از سازندگان (توصیه می‌شود)
var operation = adGroup.newKeywordBuilder()
    .withText('shoes')
    .build();
var keyword = operation.getResult();
از روش‌های ایجاد استفاده کنید (توصیه نمی‌شود)
adGroup.createKeyword('shoes');
var keyword = adGroup.keywords()
    .withCondition('KeywordText="shoes"')
    .get()
    .next();

رویکرد دوم به دلیل عملیات انتخاب اضافی که در بازیابی کلمه کلیدی دخیل است، ترجیح داده نمی‌شود. علاوه بر این، متدهای ایجاد نیز منسوخ شده‌اند.

با این حال، به خاطر داشته باشید که سازندگان، در صورت استفاده نادرست، می‌توانند مانع از دسته‌بندی عملیات اسکریپت‌های گوگل ادز شوند.

قطعه کد زیر را در نظر بگیرید که لیستی از کلمات کلیدی ایجاد می‌کند و شناسه کلمات کلیدی تازه ایجاد شده را چاپ می‌کند:

رویکرد کدگذاری قطعه کد
پیگیری عناصر به‌روز شده (توصیه می‌شود)
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() را در همان حلقه‌ای که عملیات را ایجاد می‌کند، فراخوانی می‌کند و در نتیجه اسکریپت‌های گوگل ادز را مجبور می‌کند که هر عملیات را در یک زمان اجرا کنند. رویکرد اول، اگرچه مشابه است، اما امکان دسته‌بندی را فراهم می‌کند زیرا ما تابع ()operation.getResult را در حلقه‌ای متفاوت از حلقه‌ای که در آن ایجاد شده است، فراخوانی می‌کنیم.

برای به‌روزرسانی‌های بزرگ، استفاده از آپلودهای انبوه را در نظر بگیرید

یک کار رایج که توسعه‌دهندگان انجام می‌دهند، اجرای گزارش‌ها و به‌روزرسانی ویژگی‌های موجودیت‌ها (مثلاً پیشنهادهای کلمات کلیدی) بر اساس مقادیر عملکرد فعلی است. وقتی مجبورید تعداد زیادی موجودیت را به‌روزرسانی کنید، آپلودهای انبوه معمولاً عملکرد بهتری به شما می‌دهند. برای مثال، اسکریپت‌های زیر را در نظر بگیرید که MaxCpc کلمات کلیدی که TopImpressionPercentage > 0.4 را افزایش می‌دهند:

رویکرد کدگذاری قطعه کد
استفاده از آپلود انبوه (توصیه می‌شود)

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();
انتخاب و به‌روزرسانی کلمات کلیدی بر اساس شناسه (کمتر بهینه)
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);
  }
}

در حالی که رویکرد دوم عملکرد بسیار خوبی به شما می‌دهد، رویکرد اول در این مورد ترجیح داده می‌شود، زیرا

  • اسکریپت‌های گوگل ادز محدودیتی در تعداد اشیاء قابل بازیابی یا به‌روزرسانی در یک اجرا دارند و عملیات انتخاب و به‌روزرسانی در رویکرد دوم جزو آن محدودیت محسوب می‌شود.

  • آپلودهای انبوه، هم از نظر تعداد موجودیت‌هایی که می‌توانند به‌روزرسانی کنند و هم از نظر زمان اجرای کلی، محدودیت‌های بالاتری دارند.

آپلودهای انبوه خود را بر اساس کمپین‌ها گروه‌بندی کنید

وقتی آپلودهای انبوه خود را ایجاد می‌کنید، سعی کنید عملیات خود را بر اساس کمپین والد گروه‌بندی کنید. این کار باعث افزایش کارایی و کاهش احتمال تغییرات متناقض/خطاهای همزمانی می‌شود.

دو وظیفه آپلود انبوه را در نظر بگیرید که به صورت موازی اجرا می‌شوند. یکی تبلیغات را در یک گروه تبلیغاتی متوقف می‌کند؛ دیگری پیشنهادات کلمات کلیدی را تنظیم می‌کند. اگرچه این عملیات‌ها به هم مرتبط نیستند، اما ممکن است این عملیات‌ها برای موجودیت‌های تحت یک گروه تبلیغاتی (یا دو گروه تبلیغاتی مختلف تحت یک کمپین) اعمال شوند. وقتی این اتفاق می‌افتد، سیستم موجودیت اصلی (گروه تبلیغاتی یا کمپین مشترک) را قفل می‌کند، در نتیجه باعث می‌شود وظایف آپلود انبوه روی یکدیگر مسدود شوند.

اسکریپت‌های گوگل ادز می‌توانند اجرای یک وظیفه آپلود انبوه را بهینه کنند، بنابراین ساده‌ترین کار این است که فقط یک وظیفه آپلود انبوه را برای هر حساب کاربری در یک زمان اجرا کنید. اگر تصمیم دارید بیش از یک آپلود انبوه را برای هر حساب کاربری اجرا کنید، مطمئن شوید که آپلودهای انبوه برای عملکرد بهینه، روی لیست منحصر به فرد کمپین‌ها (و موجودیت‌های فرزند آنها) عمل می‌کنند.

گزارش‌دهی

استفاده از گزارش‌ها برای دریافت آمار

وقتی می‌خواهید تعداد زیادی از موجودیت‌ها و آمار آنها را بازیابی کنید، اغلب بهتر است از گزارش‌ها به جای روش‌های استاندارد AdsApp استفاده کنید. استفاده از گزارش‌ها به دلایل زیر ترجیح داده می‌شود:

  • گزارش‌ها عملکرد بهتری را برای کوئری‌های بزرگ به شما ارائه می‌دهند.
  • گزارش‌ها به سهمیه‌های معمول دریافت نخواهند رسید.

قطعه کدهای زیر را که تعداد کلیک‌ها، نمایش‌ها، هزینه و متن تمام کلمات کلیدی که ماه گذشته بیش از ۵۰ کلیک دریافت کرده‌اند را نشان می‌دهند، مقایسه کنید:

رویکرد کدگذاری قطعه کد
استفاده از گزارش‌ها (توصیه می‌شود)
  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 استفاده کنید، نتایج را در قالبی مسطح ارائه می‌دهد. این بدان معناست که باید نتایج پرس‌وجو را برای مطابقت با سبک قدیمی تبدیل کند، که برای همه فیلدها پشتیبانی نمی‌شود و به هر فراخوانی سربار اضافه می‌کند.

پیشنهاد می‌کنیم به جای آن از جستجو استفاده کنید تا از تمام ویژگی‌های گزارش‌دهی جدید API تبلیغات گوگل بهره‌مند شوید.

GAQL را به AWQL ترجیح دهید

اگرچه از نظر فنی AWQL هنوز برای پرس‌وجوهای گزارش و فراخوانی‌های withCondition کار می‌کند، اما توصیه نمی‌شود. برای کنترل کامل بر پرس‌وجوهای خود، مطمئن شوید که به جای آن از GAQL استفاده می‌کنید.

ردیف‌های بیشتری از آنچه نیاز دارید انتخاب نکنید

سرعت اجرای گزارش‌ها (و انتخابگرها) بر اساس تعداد کل ردیف‌هایی است که توسط گزارش بازگردانده می‌شوند، صرف نظر از اینکه آیا از طریق آنها پیمایش می‌کنید یا خیر . این بدان معناست که شما همیشه باید از فیلترهای خاصی برای به حداقل رساندن مجموعه نتایج تا حد امکان استفاده کنید تا با مورد استفاده شما مطابقت داشته باشد.

برای مثال، فرض کنید می‌خواهید گروه‌های تبلیغاتی با پیشنهادهای خارج از یک محدوده خاص را پیدا کنید. ایجاد دو پرس‌وجوی جداگانه، یکی برای پیشنهادهای پایین‌تر از آستانه پایین و دیگری برای پیشنهادهای بالاتر از آستانه بالا، سریع‌تر از این است که همه گروه‌های تبلیغاتی را جمع‌آوری کنید و آنهایی را که به آنها علاقه ندارید نادیده بگیرید.

رویکرد کدگذاری قطعه کد
از دو کوئری استفاده کنید (توصیه می‌شود)
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);
  }
}

اسکریپت‌های مدیریت تبلیغات (MCC)

اجرای موازی (executeInParallel) را به اجرای سریالی ترجیح دهید

هنگام نوشتن اسکریپت برای حساب‌های مدیریتی، در صورت امکان executeInParallel() به جای اجرای سریالی استفاده کنید. executeInParallel() به اسکریپت شما زمان پردازش بیشتری (تا یک ساعت) و تا 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 Spreadsheets سعی می‌کند با ذخیره مقادیر، قطعه کد دوم را بهینه کند، اما به دلیل تعداد فراخوانی‌های API که انجام می‌شود، همچنان در مقایسه با قطعه کد اول، عملکرد ضعیفی به شما می‌دهد.