Handbook / Module 7 / Lesson 2

BigQuery Bulk Data Export: Enterprise Continuous Streams

Configure Google Search Console's native BigQuery Bulk Export, understand partitioned table schemas, and execute advanced SQL queries across billions of rows.

Enterprise 26 min read #BigQuery #SQL #Bulk Export #Enterprise Data #Data Warehousing

The Enterprise Panacea: Native BigQuery Bulk Export

For enterprise digital properties with millions of daily impressions, even the Search Console API hits quota barriers.

To solve this, Google introduced BigQuery Bulk Data Export—a native, automated pipeline that streams complete, unsampled search analytics data directly from Google’s internal indexing logs into your private Google Cloud BigQuery dataset every single day.


Setting Up BigQuery Export in 4 Steps

Google Search Console BigQuery Bulk Data Export Settings Interface Figure 7.1: The Bulk Data Export settings interface displaying active pipeline status, Google Cloud Project ID connection, target dataset configuration, and multi-region dataset location.

┌────────────────────────────────────────────────────────────────────────┐
│                     BIGQUERY EXPORT SETUP WORKFLOW                     │
│                                                                        │
│  1. Cloud Project: Open Google Cloud Console and enable BigQuery API.  │
│  2. IAM Permissions: Grant BigQuery Data Editor & Job User to:         │
│     [email protected]              │
│  3. GSC Settings: In Search Console, navigate to Settings >            │
│     "Bulk data export" and input your GCP Cloud Project ID.            │
│  4. Dataset Location: Select BigQuery dataset location (US / EU).      │
└────────────────────────────────────────────────────────────────────────┘
Google **never backfills historical data** when BigQuery Bulk Export is turned on. Data begins logging starting from the exact day you activate the export. **Activate this feature today**, even if you do not plan to write queries for another six months, to begin accumulating your permanent corporate search archive.

BigQuery Table Schemas

Once active, Google creates two daily date-partitioned tables in your dataset:

1. searchdata_site_impression

Contains site-level aggregated metrics partitioned by date:

  • data_date: Date of the impression
  • site_url: Your property domain
  • query: The search term
  • is_anonymized_query: Boolean indicating privacy masking
  • country, search_type, device
  • impressions, clicks, sum_position

2. searchdata_url_impression

Contains URL-level granular impressions:

  • Includes all fields above, plus:
  • url: The exact landing page URL that appeared on SERPs
  • is_anonymized_discover: Discover impression flag

High-Power SQL Queries for SEO Architects

A. Detect Keyword Cannibalization at Scale

Find every query where multiple URLs split impressions over the past 30 days:

SELECT
  query,
  COUNT(DISTINCT url) AS competing_urls_count,
  ARRAY_AGG(STRUCT(url, clicks, impressions) ORDER BY impressions DESC LIMIT 3) AS top_competing_pages,
  SUM(impressions) AS total_impressions,
  SUM(clicks) AS total_clicks
FROM
  `your-project.searchconsole.searchdata_url_impression`
WHERE
  data_date >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
  AND query IS NOT NULL
GROUP BY
  query
HAVING
  competing_urls_count > 1
  AND total_impressions > 500
ORDER BY
  total_impressions DESC;

B. Track Query Drift (Year-over-Year New Queries)

Find new queries driving clicks this year that generated zero impressions during the same period last year:

WITH current_period AS (
  SELECT DISTINCT query
  FROM `your-project.searchconsole.searchdata_site_impression`
  WHERE data_date >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
),
previous_period AS (
  SELECT DISTINCT query
  FROM `your-project.searchconsole.searchdata_site_impression`
  WHERE data_date BETWEEN DATE_SUB(CURRENT_DATE(), INTERVAL 395 DAY) 
                     AND DATE_SUB(CURRENT_DATE(), INTERVAL 365 DAY)
)
SELECT
  c.query AS brand_new_discovered_query,
  SUM(s.clicks) AS current_clicks,
  SUM(s.impressions) AS current_impressions
FROM
  current_period c
LEFT JOIN
  previous_period p ON c.query = p.query
JOIN
  `your-project.searchconsole.searchdata_site_impression` s ON c.query = s.query
WHERE
  p.query IS NULL
  AND s.data_date >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
GROUP BY
  brand_new_discovered_query
ORDER BY
  current_clicks DESC
LIMIT 100;

BigQuery Cost Optimization Strategies

Querying billions of rows can quickly consume cloud budget if not properly governed:

  • Always filter by data_date: The tables are partitioned by data_date. Filtering by date ensures BigQuery scans only the targeted partitions, slashing compute costs by 95%+.
  • Avoid SELECT *: Only project the explicit columns needed for your analysis (query, url, clicks).

Lab Challenge: Query Your BigQuery Stream

1. Open the Google Cloud BigQuery console. 2. Locate the Search Console dataset. 3. Run a query calculating the top 10 landing pages with the highest average position improvement over the past 14 days.