What is the difference between Query and Scan in DynamoDB?
Query finds items by partition key, optionally narrowing by sort key, and reads only matching items. Scan reads every item in the table or index and filters afterwards, so it is slower and costlier on big tables.
Explain it simply
Query is asking the librarian for "all books by this author" and going straight to that shelf. Scan is walking through every shelf in the library, picking out the matching books, and paying for each book you touched even when you leave without it.
Example
import boto3
from boto3.dynamodb.conditions import Key, Attr
table = boto3.resource("dynamodb").Table("Orders")
# Query: partition key (+ optional sort key condition)
resp = table.query(KeyConditionExpression=Key("customer_id").eq("C101"))
# Scan: reads everything, then applies the filter
resp = table.scan(FilterExpression=Attr("status").eq("PENDING"))A filter expression runs after the read, so you are still charged for all items scanned, and one response returns at most 1 MB, requiring pagination.
Use Query whenever you know the partition key. If you keep reaching for Scan, you probably need a different key design or a GSI. Scans are acceptable for small tables, one-off exports, or parallel scans in background jobs. Never run frequent scans on a big production table.
What to say in the interview
"Query goes directly to a partition key and is efficient. Scan reads the whole table and filters afterwards, and you pay for everything it reads. I design keys and GSIs so that the app uses Query and keeps Scan for small tables or offline jobs."
Common mistakes
- Thinking a filter expression reduces read cost.