Prepare and test your skills

Prepare and test your skills

Optimizing schema and key design means shaping tables, partitions, clusters, and keys so the most frequent queries scan the least data and spread load evenly. In Google Cloud, BigQuery (opens in a new tab) handles large-scale batch analytics with columnar storage, partitioning, and clustering instead of traditional indexes. Bigtable (opens in a new tab), Spanner, and Cloud SQL handle different access paths when the workload needs single-row lookups or strong transactional consistency.
The storage engine choice is the first schema decision because columnar analytics and row-based operations need different layouts. BigQuery stores data in a columnar format that is optimized for scanning large datasets and running aggregations without indexes. Bigtable is the better alternative when an analytical workload still needs fast access to a single, small set of rows, while Spanner or Cloud SQL are better alternatives when the workload requires transaction processing with strong relational consistency.
| Engine | Access path it fits | Why it fits |
|---|---|---|
| BigQuery | Batch analytics over many columns and rows | Columnar storage increases column-based operations and eliminates indexes for analytics |
| Bigtable | Single, small set of row-based reads | Row-oriented key-value access avoids scanning large analytic tables |
| Spanner or Cloud SQL | Transactional reads and writes | Strong relational consistency for operational transaction processing |
BigQuery separates storage and compute so query workers can scan relevant tables in parallel and scale independently based on demand. Because of that separation, moving an online transaction processing (OLTP) workload into BigQuery creates poor performance, so that workload should move to Cloud SQL, Spanner, or Firestore instead.
BigQuery partitioning divides a large table into segments so queries with a predicate filter on the partitioning column scan only matching partitions. Partition design must match the filter that queries use most often, such as event date for daily reporting or customer ID range for ID-filtered queries. BigQuery does not support hierarchical partitioning, and it does not support EXCHANGE PARTITION, SPLIT PARTITION, or converting a nonpartitioned table to a partitioned one, so use sharding instead of partitioning when those limits block a migration.
BigQuery implements three partitioning types for different filter columns:
TIMESTAMP or DATE column.BigQuery clustering organizes table data on disk by the values in one or more columns that are often filtered or aggregated together. Clustering stores related values together on disk, which helps optimize data retrieval when clustered columns are used as predicates. Use clustering when a table is commonly filtered and aggregated with specific columns, especially when those columns are accessed together.
BigQuery indexes do not exist as traditional B-tree indexes because columnar tables eliminate the use of indexes for batch analytics. No indexes are needed or offered in BigQuery for batch analytics, and partitioning or clustering should be used to tune query performance. GoogleSQL supports unenforced primary and foreign keys, but those keys are primarily for helping with query optimization, not for enforcing uniqueness.
For specialized lookups, BigQuery supports Search Indexes and Vector Indexes in automatic or managed form. Choose clustering for filter and aggregation performance, Search Indexes for point lookups inside text, and Vector Indexes for embedding similarity. Teradata allows explicit index creation, while BigQuery recommends this combination of clustering plus search and vector indexes.
Exam tip: BigQuery supports partitioning only by dates and integers — for strings, use clustering instead.
BigQuery nested and repeated columns let one row contain structured records and arrays instead of spreading related data across many joined tables. A nested column holds a record structure, while a repeated column holds multiple values for the same row. This design matches access paths that always fetch a parent and its children together, such as orders with line items or events with attributes.
Denormalization reduces joins and fits BigQuery's columnar layout because each nested field is still stored by column. Specify nested and repeated columns in the schema when the application reads hierarchical data as a unit. Relaxing a column from required to nullable can also support schema evolution when new access paths need optional fields.
BigQuery materialized views are precomputed views that periodically cache view query results in BigQuery storage. The cached results serve write-once, read-many reports without recomputing the full base-table scan each time. BigQuery leverages precomputed results from materialized views and whenever possible reads only delta changes from the base table to compute up-to-date results.
Smart Tuning materialized views always return current data and provide automatic query rewrite to materialized views even when the query refers to the base table. That means a dashboard query against a large base table can be redirected to the smaller precomputed result without changing the SQL. Choose materialized views when many queries repeat the same aggregations, filters, or joins over slowly changing data.
Bigtable schema design centers on row-key order and node capacity because Bigtable separates storage and compute. You can add or remove Bigtable nodes in response to query demand more seamlessly than in systems that must rebalance data across machines. You can change cluster size manually in the Google Cloud console or programmatically through the Cloud Bigtable API, and adding nodes can yield noticeable performance improvements within minutes.
Bigtable Key Visualizer is a monitoring feature in the Google Cloud console that lets you perform advanced performance tuning of key access patterns. The Bigtable console also provides prebuilt dashboards for tracking throughput and utilization metrics at the instance, cluster, and table levels, with custom views and alerts available in Cloud Monitoring. Use those signals to detect when frequent access paths concentrate on a narrow key range and need key redesign or added nodes to restore balanced performance.
Monitoring and diagnosing data access patterns means connecting observed read and write behavior to the underlying storage and compute architecture. In Google Cloud, BigQuery (opens in a new tab) separates storage in Colossus from query execution in Dremel, with resources allocated by Borg, so retrieval and ingestion bottlenecks appear in different places. Effective diagnosis starts by classifying the workload pattern, then uses column statistics, query plans with timing, and slot consumption to decide whether the limit is data layout, query shape, or compute capacity.
Characterizing the access pattern establishes the baseline that makes performance diagnostics meaningful. A workload is described by data type, current and future capacity, whether capacity should scale automatically, whether data must be accessible from outside Google Cloud, and whether multiple clients read or write simultaneously. Read-write behavior typically falls into one of four shapes: frequent writes and reads, frequent writes with occasional reads, occasional writes and reads, or occasional writes with frequent reads. Performance expectations add required I/O rate, read and write throughput, and whether production needs higher-performance storage than non-production environments.
BigQuery storage and execution architecture explains why storage growth and query slowdowns do not always move together. BigQuery stores data in Colossus in a compressed columnar format called Capacitor and operates directly on compressed data without decompressing it. Datasets are the highest-level abstraction for organizing access to tables, with schemas, labels, and partitioning used for further organization, performance isolation, and lifecycle management. Storage resources are allocated as data is consumed and deallocated when data is removed or tables are dropped, so storage scales without resizing compute.
Query execution uses a multilevel tree architecture based on Dremel, in-memory query execution, automatic storage optimization within Capacitor, 1 petabit per second total bisection bandwidth with Jupiter, and autoscaling resource management for petabyte-scale queries. Because compute, memory, and storage are treated separately, adding petabytes of storage does not by itself add query power, and slow queries with small data scans point to compute or query shape rather than storage size.
BigQuery applies several coordinated optimizations to maximize performance for cost:
BigQuery query plans, timing data, statistics, and slots are the primary diagnostics for retrieval bottlenecks. BigQuery gathers column statistics while loading data and exposes diagnostic query plan and timing information for each query. Query resources are allocated according to query type and complexity, where each query uses some number of slots, which are units of computation that include a defined amount of CPU and RAM. A plan that shows large bytes scanned, late-stage aggregation, or skewed stages combined with high slot-time points to query shape or data layout, while queuing or throttling under concurrent load points to slot quota limits.
Separation of query execution lets different projects, users, and groups query datasets in other projects with separate slot quotas and billing, so diagnosis must first isolate whether contention comes from the project running the query or the project hosting the dataset.
Exam tip: In BigQuery, slow retrieval with high bytes scanned points to partitioning, column layout, or query shape, while slow retrieval with queuing under concurrency points to slot quota; storage size alone does not determine query speed because storage and compute scale independently.
Ingestion and retrieval bottlenecks in BigQuery have different diagnostic signals because they flow through different paths. Data flows from source extracts into Cloud Storage staging, then from staging into BigQuery tables through batch load, Storage Write API, or Data Transfer Service, and only then flows from Colossus storage through Dremel workers to query results. Column statistics collected at load time improve later plan quality, so incomplete, highly fragmented, or frequently rewritten loads can degrade both load throughput and subsequent retrieval even when slot capacity is sufficient.
Partitioning improves both paths by limiting the data that must be written, scanned, and managed for lifecycle, while transfer choices affect ingestion before BigQuery diagnostics begin. If load jobs are slow but queries on already-loaded partitions are fast, the constraint sits in extraction, network bandwidth, or staging. If loads complete normally but queries scan excessive data or consume disproportionate slots, the constraint sits in table design or SQL structure.
Comparative diagnostics clarify which mitigation applies when BigQuery behavior differs from traditional engines. Oracle (opens in a new tab) gathers statistics through scheduled gathering jobs, and the optimizer uses those statistics to produce optimal execution plans, with indexes often required for fast row lookups and joins. Oracle tuning relies on engine-specific advisors and histories, while BigQuery relies on automatic column statistics plus per-query plan and timing tied to slot consumption.
| System | Statistics source | Execution insight | Scaling and tuning control |
|---|---|---|---|
| BigQuery | Column statistics gathered while loading data | Query plan and timing per query, plus slot usage by stage | Autoscaling slots per query type and complexity; separate slot quotas per project; partitioning and columnar layout |
| Oracle | Statistics gathering jobs feeding the optimizer | Optimizer execution plans with index and join choices | Pre-provisioned storage and sizing; indexes, in-memory column store, Exadata cell scan and flash cache, and Real Application Clusters (RAC) for CPU scaling |
Choose mitigation by matching the diagnostic signal to the layer that owns it. When BigQuery plans show full-table scans over selective filters, add or align partitioning and reduce scanned columns rather than adding slots. When timing shows efficient scans but high concurrency delay, adjust reservations and project assignments to isolate workloads instead of rewriting SQL. When ingestion dominates, simplify transformation placement, use schema-embedded formats such as Avro, ORC, or Parquet to reduce transfer complexity, stage in the same location as the dataset, and separate one-time historical loads from recurring incremental feeds. For Spanner, where read and write speed depends on the number of configured nodes, sustained latency or throughput limits point to node capacity, and commit timestamps can isolate rows added or modified since the last backup to distinguish incremental ingestion pressure from steady-state retrieval load.
Evaluating workload characteristics for storage selection means matching how data is written, read, and retained to a Google Cloud storage system that meets performance, resilience, and cost goals. An operational workload with frequent small reads and writes and strict latency needs points to a different system than an analytical workload with infrequent bulk reads and long retention. The choice is driven by access frequency, retention, latency tolerance, throughput needs, sharing pattern, and resilience requirements.
The access frequency and retention profile determines the most cost-efficient storage class and system for a workload. Cloud Storage buckets used for ingestion and backup should use a storage class chosen based on data-retention and access-frequency requirements, so frequently accessed operational data and rarely accessed analytical archives do not pay the same rate. Regional Cloud Storage buckets provide low-cost backup storage that is redundant across zones for database backups and transaction logs. Before selecting transfer and storage options, assess data governance, organization, and security, including whether sensitive data needs discovery, classification, and de-identification with Sensitive Data Protection.
Latency, throughput, and sharing needs separate block, file, and object storage for operational and analytical patterns. Google Cloud Hyperdisk provides better performance, flexibility, and efficiency than Persistent Disk, and with Hyperdisk Balanced you can provision IOPS and throughput separately and dynamically to tune the volume to read-heavy, write-heavy, or mixed workloads. Persistent Disk in zonal form serves single-zone tiers, while regional Persistent Disk volumes and Hyperdisk Balanced High Availability replicate data synchronously between two zones in the same region to stay available during a single-zone outage. Filestore regional instances store data shared across multiple virtual machines (VMs) in a region, such as web-tier or application-tier configuration files, tools, and centralized logs, with data replicated synchronously across three zones within the region.
The storage options compare across replication behavior and workload fit:
| System | Replication | Choose when |
|---|---|---|
| Persistent Disk | Zonal volumes stay in one zone; regional volumes replicate synchronously across two zones | The workload needs persistent block storage attached to Compute Engine (opens in a new tab) VMs |
| Google Cloud Hyperdisk | Balanced High Availability replicates synchronously between two zones | The workload needs separately tunable IOPS and throughput for varied access patterns |
| Cloud Storage | Regional buckets replicate synchronously across zones; dual-region and multi-region buckets store redundantly in two or more locations with synchronous metadata writes and asynchronous data replication | The workload needs low-cost object storage, ingestion, or backup across locations |
| Filestore | Regional instances replicate synchronously across three zones | The workload needs shared file storage mounted on multiple VMs in a region |
Exam tip: Regional storage replicates synchronously across zones, while dual-region and multi-region Cloud Storage replicates data asynchronously; dual-region buckets with turbo replication have a recovery point objective (RPO) of 15 minutes.
Resilience and location requirements constrain storage selection as much as performance does. Cloud Storage offers regional, dual-region, and multi-region bucket location types, where regional buckets replicate synchronously across multiple zones and dual-region or multi-region buckets replicate asynchronously across regions for higher availability. For shared file data, a Filestore regional instance remains available during a zone outage, and it can be replicated to a different region for robustness against region outages. Access to buckets and objects is controlled with Identity and Access Management (IAM) (opens in a new tab) at bucket and project levels, with access control lists (ACLs) for exceptions, and Cloud Storage stores or replicates data within the specified region to meet data residency requirements.
Region and cost decisions involve explicit trade-offs between latency, availability, and expense:
Capacity planning validates that the selected storage and compute can handle forecast load at the required reliability and cost. Forecasting considers the number of users, request rate, historical trends, seasonal variations, spikes during special events, and growth from business changes like expansion to new geographies. Estimating then sizes managed instance groups (MIGs), VM machine types, and the number, type, and size of persistent disks, with cost estimated through the Google Cloud Pricing Calculator.
Apply capacity controls in order to keep operational and analytical workloads reliable:
Compute Engine provides machine type recommendations to match instance types to workload compute requirements, and custom machine types save money for predictable workloads. The autoscaling capability of stateless MIGs handles traffic increases gracefully and reduces cost when demand is low, while stateful MIGs cannot be autoscaled.
BigQuery is for batch analytics over many columns and rows because its columnar storage is optimized for scanning large datasets and running aggregations without indexes. Bigtable is better when the workload needs fast access to a single, small set of row-based reads, while Spanner or Cloud SQL are better when the workload requires transaction processing with strong relational consistency.
BigQuery partitioning divides a large table into segments so queries with a predicate filter on the partitioning column scan only matching partitions, and the design must match the filter that queries use most often. The three types are tables partitioned by ingestion time based on ingestion time, tables partitioned by column based on a TIMESTAMP or DATE column, and tables partitioned by integer range based on an integer column.
BigQuery clustering organizes table data on disk by the values in one or more columns that are often filtered or aggregated together, storing related values together to optimize retrieval. Choose clustering for filter and aggregation performance, Search Indexes for point lookups inside text, and Vector Indexes for embedding similarity, since BigQuery has no traditional B-tree indexes for batch analytics.
BigQuery materialized views are precomputed views that periodically cache view query results to serve write-once, read-many reports without recomputing the full base-table scan each time. With Smart Tuning they always return current data and automatically rewrite base-table queries to the precomputed result while reading only delta changes, so choose them when many queries repeat the same aggregations, filters, or joins over slowly changing data.
An analytics team is troubleshooting severe latency regressions in analytical aggregation queries running on a Cloud Spanner Enterprise instance. Operational transactions continue to write updates, while reporting queries scan millions of rows.
The team investigates the performance diagnostics and observes the following:
SPANNER_SYS.QUERY_STATS_TOP_* shows that the AVG_COLUMNAR_READ_SHARE metric for these queries is near 0%.SELECT *.Which actions should the team take to diagnose and mitigate this retrieval bottleneck?
Last updated