Global Secondary Index (GSI) concept in DynamoDB - Time & Space Complexity
When using a Global Secondary Index (GSI) in DynamoDB, we want to know how the time to find data changes as the amount of data grows.
We ask: How does searching with a GSI scale when the table gets bigger?
Analyze the time complexity of querying a DynamoDB table using a GSI.
const params = {
TableName: "Orders",
IndexName: "CustomerIdIndex",
KeyConditionExpression: "CustomerId = :cid",
ExpressionAttributeValues: {
":cid": { S: "12345" }
}
};
const result = await dynamodb.query(params).promise();
This code queries the "Orders" table using a GSI named "CustomerIdIndex" to find all orders for a specific customer.
Look for repeated actions that affect time.
- Primary operation: Querying the GSI partitions that match the customer ID.
- How many times: Depends on how many orders the customer has; each matching item is read once.
As the number of orders for a customer grows, the time to get all results grows too.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 orders | About 10 reads |
| 100 orders | About 100 reads |
| 1000 orders | About 1000 reads |
Pattern observation: The time grows roughly in direct proportion to the number of matching items.
Time Complexity: O(n)
This means the time to get results grows linearly with how many matching items the GSI returns.
[X] Wrong: "Using a GSI always makes queries run in constant time, no matter how many items match."
[OK] Correct: The GSI helps find matching items quickly, but reading all matching items still takes time proportional to how many there are.
Understanding how GSIs affect query time helps you design efficient DynamoDB tables and answer questions about scaling data access.
What if we added a filter expression after querying the GSI? How would that affect the time complexity?
Practice
Global Secondary Index (GSI) in DynamoDB?Solution
Step 1: Understand what a GSI does
A GSI lets you query the table using different keys than the main primary key.Step 2: Compare options to GSI purpose
Options A, C, and D describe unrelated features like backup, size, or encryption, which are not GSI functions.Final Answer:
To allow queries using alternate keys different from the primary key -> Option AQuick Check:
GSI = alternate query keys [OK]
- Confusing GSI with backups
- Thinking GSI increases table size
- Assuming GSI encrypts data
Solution
Step 1: Check the correct JSON structure for GSI
TheGlobalSecondaryIndexesmust be an array of objects, each withIndexName,KeySchema, andProjection.Step 2: Validate key schema and projection
{ "GlobalSecondaryIndexes": [ { "IndexName": "GSI1", "KeySchema": [ {"AttributeName": "GSIKey", "KeyType": "HASH"}, {"AttributeName": "SortKey", "KeyType": "RANGE"} ], "Projection": {"ProjectionType": "INCLUDE", "NonKeyAttributes": ["Attr1"]} } ] } correctly uses an array, has both HASH and RANGE keys, and a valid projection with included attributes.Final Answer:
Correct GSI JSON with array, keys, and projection -> Option DQuick Check:
GSI JSON array with keys and projection = A [OK]
- Using object instead of array for GlobalSecondaryIndexes
- Wrong key types or missing HASH key
- Incorrect property names like SecondaryIndexes
Category (HASH key) and Price (RANGE key), what will the following query return?Query({
IndexName: 'CategoryPriceIndex',
KeyConditionExpression: 'Category = :cat and Price > :minPrice',
ExpressionAttributeValues: {
':cat': 'Books',
':minPrice': 20
}
})Solution
Step 1: Understand KeyConditionExpression with GSI keys
The query uses the GSI's HASH key 'Category' with equality and RANGE key 'Price' with a greater than condition, which is valid.Step 2: Interpret the query filter
The query returns items where Category equals 'Books' AND Price is greater than 20, matching the GSI keys.Final Answer:
All items where Category is 'Books' and Price is greater than 20 -> Option CQuick Check:
GSI query with HASH and RANGE keys = All items where Category is 'Books' and Price is greater than 20 [OK]
- Confusing AND with OR in KeyConditionExpression
- Thinking Price can't be in KeyConditionExpression
- Assuming query returns all items ignoring Category
IndexName: 'UserEmailIndex' on attribute Email as HASH key. Your query on this GSI returns no results even though items with matching emails exist. What is the most likely cause?Solution
Step 1: Understand GSI indexing timing
When a GSI is created after data insertion, it takes time to index existing items. Queries may return empty until indexing completes.Step 2: Evaluate other options
You used the primary key instead of the GSI key in the query is about query keys but question states query is on GSI. The Email attribute is not projected to the GSI is invalid because HASH key attributes must be projected automatically. DynamoDB does not support querying on GSIs is false; DynamoDB supports GSI queries.Final Answer:
The GSI was created after the items were inserted and has not yet indexed them -> Option AQuick Check:
New GSI indexing delay causes empty query [OK]
- Assuming GSI queries always return instantly after creation
- Confusing projection with key attributes
- Believing DynamoDB doesn't support GSI queries
UserID (HASH) and a GSI named OrderDateIndex with OrderDate as HASH and Status as RANGE key. You want to efficiently find all orders placed on '2023-05-01' with status 'Shipped'. Which query approach is best?Solution
Step 1: Identify the best index for the query
The GSIOrderDateIndexhasOrderDateas HASH andStatusas RANGE key, matching the query conditions.Step 2: Choose efficient query method
Querying the GSI with KeyConditionExpression on HASH and RANGE keys is efficient and uses indexes. Scans are less efficient and should be avoided.Final Answer:
Query the OrderDateIndex with KeyConditionExpression 'OrderDate = :date and Status = :status' -> Option BQuick Check:
Use GSI query with HASH and RANGE keys for best performance [OK]
- Using Scan instead of Query causing slow performance
- Querying main table with wrong keys
- Filtering after Scan instead of using KeyConditionExpression
Ready to prove it?
Pass the test and this pattern moves unknown
