Prepare and test your skills

Prepare and test your skills

Diagnosing data-related performance issues means tracing slow queries to how data is stored, modeled, and maintained rather than to machine size alone. In Google Cloud, BigQuery (opens in a new tab) exposes this through bytes read, bytes shuffled, CPU consumed, and bytes written, while Cloud SQL for PostgreSQL and AlloyDB for PostgreSQL expose it through table structure, indexes, statistics freshness, and maintenance history. Resolution follows the data: refresh statistics and maintenance, correct schema and indexing, then re-architect with partitioning or sharding only when tuning is not enough.
Query work signals in BigQuery show whether poor performance comes from data layout or from contention for capacity. Queries that do less work run faster, consume fewer resources, and cost less, so evaluation starts with how much work each query performs. The documented factors form a complete check:
High bytes read with selective filters points to missing pruning from partitioning or indexing, while high shuffle points to joins and aggregations moving too much data between stages. BigQuery provides the query execution graph to analyze slot contention and insufficient shuffle quota, Cloud Monitoring and administrative resource charts to track how jobs consume resources over time, and Gemini Cloud Assist to analyze individual jobs. BigQuery BI Engine (BI Engine) accelerates many business intelligence tool patterns by intelligently caching frequently used data in memory without query rewrites, which helps separate a caching opportunity from a true modeling flaw.
Maintenance and statistics freshness determines whether the optimizer chooses an efficient execution plan for current data. Cloud SQL for PostgreSQL and AlloyDB for PostgreSQL depend on routine operations such as index defragmentation, statistics updates, vacuum analyze, and reindex of heavily updated tables. Diagnosis checks if and when these operations last ran on the affected tables and indexes, and whether normal activity changed, for example by adding a new column or applying a large volume of updates.
Stale statistics cause the planner to misestimate row counts and choose index scans, join orders, or access paths that no longer fit the data. Investigation therefore pairs the slow-query log with execution plans to verify whether critical queries use available indexes and where locks and waits on other resources appear. For PostgreSQL engines, VACUUM reclaims dead tuples and freezes table data, and its throughput depends on system memory and the maintenance_work_mem parameter because more memory lets more tuples batch in each iteration. Avoiding too many read replicas matters because excess replicas hinder VACUUM, and setting the INDEX_CLEANUP parameter to OFF allows faster cleanup and freezing of table data when large indexes make index scans expensive. AlloyDB for PostgreSQL exposes these signals through the System Insights dashboard for resource metrics such as peak connections and maximum replication lag, Query Insights to trace a problematic query to its source, and audit logs for change history.
Data modeling remediation fixes the long-term cause when tuning alone cannot compensate for poor structure. The first questions are whether tables are properly structured for the workload, whether columns use correct data types, and whether the data model matches read-heavy, write-heavy, or mixed access. Adding indexes to support critical queries speeds selective access, while eliminating non-critical indexes and foreign keys reduces write and maintenance overhead, and rewriting complex queries and joins reduces shuffle and CPU.
When tuning is insufficient, re-architecture changes how data is divided and retained. Partitioning tables narrows the bytes each query must read, and archiving data that is no longer needed removes it from the hot path entirely. Normalizing the structure reduces duplication and update anomalies, but denormalizing can improve read performance by avoiding expensive joins, so the choice depends on whether the workload is dominated by consistent writes or by fast analytical reads. Disk performance on Cloud SQL depends on disk size and vCPU count, so an undersized instance can mask a modeling problem, but vertical scale-up only partially compensates while a proper data model provides the durable fix.
The three scale and structure paths differ in what they scale, what they cost, and what new risk they create:
| Remediation path | What it scales | Effort and dependency | Key tradeoff |
|---|---|---|---|
| Read replicas | Read throughput by routing read queries from applications to a replica and offloading the primary instance | Moderate effort; applications must change connections, optionally behind HAProxy or read pool instances | Offloads reads but does not fix write or modeling flaws, and too many replicas hinder VACUUM |
| Partitioning and indexing | Query selectivity by dividing tables and supporting critical access paths | Higher effort than tuning; may require data migration | Long-term reduction in bytes read, but requires design and migration work |
| Database sharding | Both writes and reads by splitting one instance into multiple smaller instances by criteria such as customer or subject | Complicated re-architecture of database and applications plus data migration | Horizontal scale at the cost of higher operational complexity and risk of unbalanced shards, called hotspots, that erase the benefit |
Exam tip: Too many read replicas hinder VACUUM on Cloud SQL for PostgreSQL and AlloyDB for PostgreSQL, so scale reads only to the point where maintenance can still complete.
Capacity contention in BigQuery must be separated from data design before changing tables. BigQuery offers on-demand pricing with a shared pool of capacity billed by bytes processed, and capacity-based pricing with dedicated query processing capacity measured in slots where bytes processed are included in the capacity price. Capacity-based reservations support fixed slot commitments plus autoscaling slots that add dynamic capacity based on workload, and repeated queries on the same data show larger performance variation under on-demand slots than under slot reservations.
If the execution graph shows slot contention rather than large input, shuffle, or output, the fix is capacity or scheduling rather than remodeling. Optimization then iterates until goals are met: first assess the environment and optimization loop, then establish requirements and goals, then optimize the environment, then tune the loop. Focusing this loop on the workloads that matter most to analytics pipelines avoids spending modeling effort on contention or micro-optimizations that do not improve cost or reliability.
Optimizing query syntax and resource allocation in BigQuery (opens in a new tab) means reducing the work expressed in SQL and ensuring enough slot capacity is available when the query runs. BigQuery follows a single principle: queries that do less work perform better. A query that reads fewer bytes, shuffles fewer bytes between stages, uses less CPU, and writes less output runs faster, consumes fewer resources, and lowers cost with fewer failures.
What determines work and speed in BigQuery is the combination of input, movement, computation, output, capacity, and SQL patterns. Evaluating a slow query means checking each factor to find which one dominates resource use. The six evaluation factors are:
Resource contention is evaluated separately from single-query efficiency. Cloud Monitoring, BigQuery administrative resource charts, and Gemini Cloud Assist for job analysis monitor how jobs consume resources over time and reveal whether slowness comes from one expensive query or from many queries competing for slots.
Efficient SQL patterns in BigQuery are choices that reduce bytes read, bytes shuffled, CPU consumed, and bytes written. Refactoring follows the same logic: filter earlier so later stages receive less data, project only needed columns so less data is read and materialized, and use joins and functions that minimize intermediate output. A JOIN stage that generates far more output rows than input rows, for example, indicates an opportunity to filter earlier in the query.
Some workloads can improve without rewriting SQL. BigQuery BI Engine (BI Engine) is a fast, in-memory analysis service that accelerates many SQL queries, especially those generated by business intelligence tools, by intelligently caching frequently used data. BI Engine is built into BigQuery, so acceleration often occurs without query modifications. Optimization also involves tradeoffs, because advanced SQL syntax can reduce understandability for non-experts and micro-optimizing noncritical workloads can divert effort from more important pipeline improvements. Focus optimization effort on workloads that matter most to data analytics pipelines.
Slot capacity in BigQuery is computational throughput measured in slots, which are Google's proprietary units of capacity required to execute SQL queries. BigQuery breaks down the capacity required for each query stage into slots and continuously calculates how many slots queries need as they execute. Capacity is provisioned through two pricing models that balance cost predictability against flexibility.
| Pricing model | How capacity is provided | How cost is charged |
|---|---|---|
| On-demand pricing | Shared pool of capacity available to the project, with a default limit of 2,000 slots per project and opportunistic bursting beyond that limit that is not guaranteed | Based on the number of bytes processed by each query run |
| Capacity-based pricing | Dedicated query processing capacity allocated through slot reservations, with a minimum of 100 slots, using fixed slot commitments plus autoscaling slots that add dynamic capacity based on workload | Cost of all bytes processed is included in the capacity price |
Choose capacity-based pricing when monthly spend must be consistent or when more capacity is needed than the on-demand shared pool provides. Capacity-based pricing is recommended for enterprise workloads with many concurrent reporting and extract, load, transform (ELT) queries that have predictable consumption. Repeated queries on the same data show performance variation under both models, and that variation is generally larger for on-demand slots than for slot reservations.
Concurrency in BigQuery is controlled by how many slots are available in the project for on-demand pricing or in the reservation for capacity-based pricing. BigQuery automatically determines how many queries can run concurrently from that available slot pool. Queries that require more slots than are available are queued until processing resources become available.
After a query begins execution, BigQuery calculates how many slots each query stage uses based on stage size and complexity and the number of slots available. BigQuery uses fair scheduling to ensure that each query receives enough capacity to progress. Access to more slots does not always make an individual query faster, but a larger slot pool can improve large or complex queries and highly concurrent workloads. To improve performance, modify slot reservations or set a higher limit for slots autoscaling, including managing reservations with Gemini Cloud Assist natural-language prompts.
Exam tip: More slots do not always make a query faster, but high slot utilization plus high wait times in execution plans indicates a need for additional slots or a higher autoscaling limit.
The BigQuery query plan is the per-execution breakdown that shows how BigQuery converted declarative SQL into distributed work. Understanding the query plan is critical for effective optimization because the plan includes execution statistics such as bytes read and slot time consumed plus details about different stages of execution. The query execution graph provides a graphical interface for viewing the plan and diagnosing which stages dominate resource use.
During execution, BigQuery converts the SQL statement into a graph of execution that is broken into query stages composed of granular execution steps. The stages run on a heavily distributed parallel architecture where many workers execute units of work in parallel, and stages communicate with one another through a fast, distributed shuffle architecture. To estimate computational cost, look at total slot seconds consumed by the query, where lower slot seconds leave more resources available to other queries in the same project. Retrieve plan and timeline data through the jobs.get API method or the INFORMATION_SCHEMA.JOBS view, which also feeds BigQuery Visualizer, an open source tool that visually represents the flow of execution stages.
Analyzing query execution plans and performance metrics means tracing how a declarative SQL statement is turned into distributed work and where that work becomes expensive. In BigQuery (opens in a new tab), the SQL statement flows into a graph of execution that is split into stages and steps run by many parallel workers. In Cloud SQL (opens in a new tab), load flows from the instance metrics into the Query insights dashboard where high-load periods can be investigated for root causes and fixes.
Factors that shape work in BigQuery jobs are input, movement, compute, output, capacity, and query patterns. Queries that do less work run faster, consume fewer resources, and cost less with fewer failures. The six evaluation factors are:
These factors are monitored over time with Cloud Monitoring and administrative resource charts, which show how jobs consume resources and whether slowness comes from a single query or contention across queries. Gemini Cloud Assist can analyze a specific job, while BigQuery BI Engine (BI Engine) accelerates many business intelligence queries by caching frequently used data in memory without query changes. Optimization involves tradeoffs, so effort is best focused on workloads that matter most to data pipelines rather than micro-optimizations or complex syntax that reduces understandability.
The query plan in BigQuery is the per-execution record of how the SQL statement was run, including execution statistics and stage-level detail. BigQuery generates a query plan each time a query runs, and the plan reports bytes read, slot time consumed, and the breakdown of execution stages. The query execution graph is the graphical view of that plan used to see which stages dominate resource use and diagnose performance issues.
When BigQuery executes a query job, data flows from the declarative SQL statement to a graph of execution, then to query stages, then to granular execution steps run by parallel workers. Stages model units of work that many workers execute in parallel, and stages communicate with one another through a fast, distributed shuffle architecture. Programmatic access to the same plan and timeline flows from the job to either the jobs.get API method or the INFORMATION_SCHEMA.JOBS view, which the open-source BigQuery Visualizer can render as stage flow.
To estimate computational cost, compare total slot seconds consumed by the query, where lower slot seconds leave more capacity for other queries in the same project. A stage-level bottleneck appears when one stage consumes disproportionate bytes, shuffle, or slot time, such as a JOIN stage that generates far more output rows than input rows. That pattern indicates data should be filtered earlier to reduce rows before the join, although the managed nature of the service means not every low-level detail is directly actionable.
Exam tip: A JOIN stage with far more output rows than input rows points to filtering earlier, while high bytes passed to the next stage or per slot points to excessive shuffling.
Slots in BigQuery are the proprietary units of computational capacity required to execute each stage of a query. During processing, BigQuery breaks down the capacity needed for each stage by stage size, stage complexity, and slots available, then allocates that capacity with fair scheduling so each query has enough capacity to progress. Queries that require more slots than are available are queued until processing resources become available.
Capacity choice controls billing, concurrency, and performance stability:
| Model | Billing basis | Capacity source | Choose when |
|---|---|---|---|
| On-demand | Bytes processed per query from a shared pool | Slots available in the project | Query volume is variable and paying per query is preferred |
| Capacity-based | Dedicated slots through reservations, bytes included | Slots available in the reservation | Monthly spend must be predictable or more capacity and concurrency are needed |
On-demand projects are limited by default to a maximum of 2000 slots, although BigQuery might burst beyond that limit without guarantee. Capacity-based pricing starts at a minimum of 100 slots and can add autoscaling slots that expand dynamically with workload demand. Repeated queries on the same data vary more under on-demand slots than under slot reservations, and more slots do not always make a single query faster. A larger slot pool helps most for large or complex queries and highly concurrent reporting and extract-load-transform workloads, which can be improved by modifying reservations or raising the autoscaling limit.
Diagnosis in Cloud SQL centers on the Query insights dashboard and the instance overview page, which expose database load, active queries, and AI-assisted investigations. If a specific active query is blocked or runs much longer than expected, the blocked query can block dependent queries, and Cloud SQL allows termination of that long-running or blocked query. Prompt-based analysis can also summarize top queries by latency and identify the slowest query within the selected time-range filter.
High-load troubleshooting starts from a chart and flows into an investigation with ordered steps. First, the operator selects a metric such as CPU utilization and a time range of 1 hour, 6 hours, 1 day, 7 days, 30 days, or a custom range. Then, the operator zooms into the high-load interval on the database load chart. Then, the operator selects Investigate performance to start Gemini Cloud Assist analysis. Only after about two minutes, the Investigation details pane opens with Issue, Observations, and Hypotheses.
The Issue section in the Investigation details pane describes the problem with start and stop time, the Observations section lists evidence such as lock contention or longer-than-expected lock wait ratio, and the Hypotheses section lists recommended actions. Cloud SQL calculates expected load from the 24 hours before the selected range, analyzes the full period when less than 24 hours is selected, and analyzes only the last 24 hours when more is selected. The baseline uses the prior 24 hours except on Monday, when it uses the seventh prior day to account for weekly patterns. During analysis, Cloud SQL compares baseline aggregates against the analysis window across metrics:
A significant threshold change in a key metric indicates a possible condition that explains the high load, and the Hypotheses provide actionable remediation when analysis supports a recommendation.
Evaluate input bytes read, bytes shuffled between stages and per slot, CPU consumed, bytes written, available slot capacity and concurrency, and SQL query patterns. Queries that do less work run faster, consume fewer resources, and cost less with fewer failures, so high bytes read with selective filters points to missing pruning while high shuffle points to joins and aggregations moving too much data between stages.
Choose BigQuery capacity-based pricing when monthly spend must be consistent or predictable or when more capacity is needed than the on-demand shared pool provides. On-demand pricing uses a shared pool with a default limit of 2,000 slots per project and is billed by bytes processed, while capacity-based pricing uses dedicated reservations with a minimum of 100 slots plus autoscaling slots and includes bytes processed in the capacity price.
Stale statistics cause the planner to misestimate row counts and choose index scans, join orders, or access paths that no longer fit the data. VACUUM reclaims dead tuples and freezes table data with throughput that depends on system memory and the maintenance_work_mem parameter, and too many read replicas hinder VACUUM so reads should be scaled only to the point where maintenance can still complete.
A data engineering team maintains a Cloud SQL for PostgreSQL instance that serves data models for executive reporting dashboards. During morning peak hours, numerous concurrent dashboard sessions execute complex queries involving large ORDER BY, GROUP BY, and multi-table join operations.
Database logs reveal recurring Out of Memory: Killed process (postgres) errors and connection terminations (terminating connection due to administrator command). Monitoring shows high active session counts and severe RAM saturation.
Which resource configuration adjustment should the data engineer implement to balance query performance and prevent out-of-memory errors?
Last updated