Self-Assessment Quiz: Incremental Processing and Slowly Changing Dimensions
Twenty questions. Aim for 16 or more. Questions 6, 12, and 19 are the ones that separate people who have run an incremental model in production from people who have configured one.
Question 1
The rule of thumb for going incremental is roughly:
- A. Any table over a million rows
- B. Above ~$5,000/year saved, or when the full refresh does not fit the window
- C. Always, for facts
- D. Whenever the source supports it
Question 2
A third reason a model must be incremental, unrelated to cost:
- A. It has a surrogate key
- B. The source no longer retains the history, so the fact table is the system of record
- C. It is a dimension
- D. It uses window functions
Question 3
The three questions every incremental model answers are what is new, how new combines with old, and:
- A. How fast it runs
- B. What happens if it runs twice
- C. Who owns it
- D. Which warehouse it targets
Question 4
materialized='incremental' with no unique_key gives you:
- A. A merge
- B. An append, which is not idempotent
- C. An error
- D. A full refresh
Question 5
The question that selects an idempotency strategy is:
- A. Which is fastest
- B. What is the smallest unit I can rewrite completely
- C. Which does my engine support
- D. How large is the table
Question 6
Build-aside-and-swap's real value is:
- A. Speed
- B. You can assert against the new table before it becomes visible, so a failure leaves the old data live
- C. Lower storage
- D. Atomicity on every engine
Question 7
dbt build --full-refresh:
- A. Rebuilds in place
- B. Drops the table and rebuilds it, so it does not exist meanwhile
- C. Merges everything
- D. Is always safe
Question 8
If a full refresh fails halfway you have:
- A. The old table
- B. Neither the old table nor a new one
- C. A partial new table plus the old
- D. An automatic rollback
Question 9
insert_overwrite on BigQuery:
- A. Replaces matching rows
- B. Replaces whole partitions, and nothing checks that your
WHEREmatches yourpartition_by - C. Appends
- D. Requires a unique key
Question 10
on_schema_change defaults to:
- A.
append_new_columns - B.
fail - C.
ignore— so a new source column is silently dropped - D.
sync_all_columns
Question 11
A watermark of > MAX(updated_at) fails because:
- A. The column may be null
- B. A transaction that began before your read and commits after it carries a timestamp below the watermark
- C. Timestamps are not indexed
- D.
MAXis slow
Question 12
A lookback window without a merge strategy:
- A. Is fine
- B. Duplicates the lookback period every night, without bound
- C. Is slower
- D. Loses rows
Question 13
A lookback should be sized from:
- A. p99 of arrival lag
- B. p99.9
- C. Above the observed maximum, with margin
- D. The batch interval
Question 14
Why not make the lookback very large?
- A. It is not allowed
- B. It is what the merge scans, and it hides an upstream whose lag is degrading
- C. It breaks idempotency
- D. It requires more storage
Question 15
The SCD type decision is made:
- A. Per dimension
- B. Per column
- C. Per warehouse
- D. Once, at project setup
Question 16
A Type 2 surrogate key identifies:
- A. The customer
- B. A version of the customer
- C. The load batch
- D. The natural key
Question 17
valid_to = NULL on the current row causes:
- A. An error
- B. A point-in-time join to silently drop every fact belonging to a current version
- C. Duplicate rows
- D. Slower joins
Question 18
check_cols: all in a dbt snapshot:
- A. Is the safe default
- B. Turns the dimension into a change-log keyed on whichever source column changes most
- C. Is required for the check strategy
- D. Only tracks primary keys
Question 19
After a broken dimension load is repaired, facts written with customer_key = -1:
- A. Are corrected automatically
- B. Keep that value forever — the watermark has passed them and nothing about them changed
- C. Are reprocessed on the next full refresh only
- D. Are deleted
Question 20
An incremental model's cost is dominated by:
- A. The source read
- B. The target scan, which is why
incremental_predicatesmatters - C. Network transfer
- D. The number of columns
Answer Key
1. B — §20.1. silver.events saves $47,304/year; `fct_order_item` saves $649 and cost two
incidents.
2. B — §20.1. And the bar for that model's assertions is correspondingly higher, because the bug in Case Study 2 would have been permanent.
3. B — §20.2. The other two announce themselves.
4. B — §20.5. The configuration that produces it is the one you get by not specifying anything, which is why Chapter 1's incident keeps being recreated.
5. B — §20.3, 🔁 callout. Partition → overwrite. Row → merge. Whole table → swap. Nothing → you have an append-only log.
6. B — §20.3. Chapter 19's "stale beats wrong," implemented.
7. B — §20.4. At 05:50 that is a missed 6am SLA in the most confusing possible way.
8. B — §20.4. Recovery is time travel if you have it and a restore if you do not.
9. B — §20.5. Three days of a monthly-partitioned table replaces the whole month.
10. C — §20.5, 🧭 callout. Chapter 17's compatibility discussion, in a place nobody looks.
11. B — §20.7 and Chapter 13 §13.4. The row is lost, not delayed.
12. B — §20.7. It converts a data-loss bug into a duplication bug — from a change made to improve correctness.
13. C — §20.7. The rows you lose are in the tail by definition, so a percentile window is the same failure at a smaller scale.
14. B — Case Study 2, 📐 callout. Size it just above the maximum and alert when a recovered row's lag exceeds half the window — that makes the window a sensor.
15. B — §20.8. email is Type 1; region is Type 2; putting both in one Type 2 dimension makes
every email correction a new version.
16. B — §20.9. Which is what makes the fact join work: the order stays attached to Ohio forever.
17. B — §20.9, ⚠️ callout. x < NULL is NULL, which is not TRUE. In a dimension where most rows
are current, that is most of your data — and it returns a smaller result rather than an error.
18. B — §20.10 and Case Study 1. 1,904,221 rows to 11,355,581 in five months.
19. B — §20.11 and Chapter 19 Case Study 2. Rebind on a schedule so nobody has to remember.
20. B — §20.12. The opposite of most people's intuition, and invisible unless you read the query profile.
Topic map
| Missed | Reread |
|---|---|
| 1, 2 | §20.1 — decide whether before how |
| 3 | §20.2 — the three questions |
| 4, 5, 6 | §20.3 — idempotency |
| 7, 8 | §20.4 — backfills |
| 9, 10 | §20.5 — strategies by engine |
| 11, 12, 13, 14 | §20.7 and Case Study 2 — late arrivals |
| 15, 16, 17 | §20.8, §20.9 — SCD |
| 18 | §20.10 and Case Study 1 — check_cols |
| 19 | §20.11 — late-arriving dimensions |
| 20 | §20.12 — the target scan |