Composite Index Optimization for Slow Queries in Cloud SQL
Network Topology
Refer to the exhibit. You are analyzing a slow query in Cloud SQL for PostgreSQL. The execution plan shows a sequential scan. Which index should you create to most effectively improve query performance?
Quick Answer
The answer is to create a composite index on `(user_id, created_at)`. This is correct because when a slow query in Cloud SQL for PostgreSQL performs a sequential scan, it often lacks an index that supports both the filter and the sort order. A composite index on `(user_id, created_at)` enables the database to first seek the exact `user_id` via an index seek, then efficiently access rows in `created_at` order, eliminating the need for a costly sequential scan and separate sort operation. On the Google Professional Cloud Database Engineer exam, this scenario tests your understanding of composite index optimization for slow queries in Cloud SQL, specifically how column order matters: place equality columns first, then range or sort columns. A common trap is creating separate single-column indexes, which PostgreSQL cannot combine as effectively for both filtering and ordering. Remember the mnemonic "Equal first, then range" to quickly recall the correct column order for composite indexes.
⚠ Common exam trap
Google Cloud often tests the misconception that any composite index with the right columns will work, but the column order matters critically — candidates pick `(created_at, user_id)` thinking it covers both, not realizing the leading column must match the equality filter for optimal performance.
Answer choices
Why each option matters
Answer the question above first, then reveal the full breakdown to understand why each option is right or wrong.
Correct answer & explanation
✓
CREATE INDEX idx_orders_user_created ON orders(user_id, created_at);
The query likely filters on `user_id` and then sorts or filters by `created_at`. A composite index on `(user_id, created_at)` allows PostgreSQL to first narrow down by `user_id` using index seek, then efficiently access rows in `created_at` order, avoiding a sequential scan. This matches the most common pattern for slow queries involving equality on `user_id` and range or ordering on `created_at`.
Answer analysis
Option-by-option breakdown
For each option: why learners choose it and why it is or isn't the right answer here.
- ✗
CREATE INDEX idx_orders_partial ON orders(created_at) WHERE user_id = 123;
Why it's wrong here
Only helps for user_id 123; other users still see sequential scans.
- ✗
CREATE INDEX idx_orders_created_at ON orders(created_at);
Why it's wrong here
Does not cover the equality condition on user_id.
- ✗
CREATE INDEX idx_orders_created_user ON orders(created_at, user_id);
Why it's wrong here
Less efficient because range condition on created_at reduces index usefulness for user_id.
- ✓
CREATE INDEX idx_orders_user_created ON orders(user_id, created_at);
Why this is correct
Allows index seek on user_id then range scan on created_at.
Go deeper
Related to this question
About these practice questions
This PCDE question is part of Courseiva's 1,446-question bank — original exam-style content with full explanations and wrong-answer analysis, never real exam questions or exam dumps. Learn why practice questions differ from exam dumps →
Same concept, more angles
2 more ways this is tested on PCDE
These questions test the same concept from different angles. Work through them to make sure you can recognise it however the exam phrases it.
Variation 1. Your company runs a large e-commerce application on Google Cloud using Cloud SQL for MySQL (version 8.0) with 2 TB of data. The database experiences intermittent performance degradation during peak hours (10am-2pm). Cloud Monitoring shows a spike in CPU utilization to 90% and increased query latency. The database has been running for 6 months with default settings. You notice many slow queries like "SELECT * FROM orders WHERE customer_id=12345 ORDER BY order_date DESC LIMIT 10" that take 5-10 seconds. The orders table has 50 million rows, customer_id has a B-tree index, and order_date is not indexed. The query execution plan indicates a full table scan and a filesort. What is the most effective course of action to resolve the performance issue?
hard- ✓ A.Add a composite index on (customer_id, order_date)
- B.Create multiple read replicas to offload read traffic
- C.Partition the orders table by month using range partitioning
- D.Increase the memory size of the Cloud SQL instance to 30 GB
Why A: The slow query uses a WHERE clause on customer_id (which is indexed) and an ORDER BY on order_date (not indexed). The index on customer_id alone is insufficient because the query still requires sorting, leading to a filesort. Adding a composite index on (customer_id, order_date) allows the database to retrieve rows for a specific customer in sorted order without a full scan or filesort. Option B (increasing memory) may help but does not address the root cause. Option C (read replicas) offloads read traffic but does not fix the query plan. Option D (partitioning) might help with data management but is not as direct or efficient as adding the appropriate index.
Variation 2. You are managing a Cloud SQL for MySQL instance that supports a web application. Recently, users have reported that the application is responding slowly during peak hours. You examine the Query Insights dashboard and see that a specific query is running frequently and has a high execution time. The query involves JOINs on three tables, each with tens of thousands of rows. The query plan shows a full table scan on two tables. What should you do first to improve performance?
easy- A.Enable the query cache flag in Cloud SQL database flags.
- B.Increase the instance size to provide more memory and CPU.
- ✓ C.Add indexes on the columns used in JOIN conditions.
- D.Rewrite the query to use subqueries instead of JOINs.
Why C: Adding appropriate indexes on the join columns will reduce full table scans, which is the most effective immediate action. Option A (enabling query cache) is not recommended because query cache is deprecated in MySQL 8.0 and does not address the root cause of full table scans. Option B (increasing instance size) may provide more resources but does not fix the inefficient query plan, making it a costly temporary solution. Option D (rewriting with subqueries) could change the execution plan but is more complex and time-consuming; indexing is the standard first step for JOIN performance.
JA
Written by Johnson Ajibi, MSc IT Security
Senior Network & Security Engineer · founder of Courseiva
This PCDE practice question is part of Courseiva's free Google Cloud certification practice question bank. Courseiva provides original exam-style practice questions with explanations, topic-based practice, mock exams, readiness tracking, and study analytics to help learners prepare for the PCDE exam.