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 WHERE matches your partition_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. MAX is 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_predicates matters
  • 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