Incremental strategies (append, merge, delete+insert) in dbt - Time & Space Complexity
When working with incremental models in dbt, it's important to understand how the time to update data grows as the data size increases.
We want to know how the cost of appending, merging, or deleting and inserting data changes with bigger datasets.
Analyze the time complexity of these incremental strategies in dbt.
-- Append strategy
{{ config(materialized='incremental', incremental_strategy='append') }}
select * from source_table
-- Merge strategy
{{ config(materialized='incremental', incremental_strategy='merge', unique_key='id') }}
select * from source_table
-- Delete + Insert strategy
{{ config(materialized='incremental', incremental_strategy='delete+insert', unique_key='id') }}
select * from source_table
This code shows three ways dbt updates data incrementally: adding new rows, merging changes, or deleting and inserting rows.
Look at what repeats as data grows.
- Primary operation: Scanning and processing new or changed rows.
- How many times: Once per incremental run, but depends on how many rows are new or updated.
As the number of new or changed rows grows, the work to update the table grows too.
| Input Size (new/changed rows) | Approx. Operations |
|---|---|
| 10 | 10 operations (simple append or merge) |
| 100 | 100 operations (more rows to process) |
| 1000 | 1000 operations (larger update) |
Pattern observation: The time grows roughly in direct proportion to the number of rows changed or added.
Time Complexity: O(n)
This means the time to update grows linearly with the number of new or changed rows processed.
[X] Wrong: "Incremental updates always take the same time regardless of data size."
[OK] Correct: The time depends on how many rows are new or changed, so bigger updates take more time.
Understanding how incremental strategies scale helps you explain data pipeline efficiency and design choices clearly in real projects.
What if the incremental strategy used a complex join instead of a simple key match? How would the time complexity change?
Practice
Solution
Step 1: Understand the append strategy
The append strategy adds only new rows to the existing table without changing any existing data.Step 2: Compare with other strategies
Merge updates existing rows and adds new ones; delete+insert replaces matching rows; truncate removes all data first.Final Answer:
append -> Option CQuick Check:
append = add new rows only [OK]
- Confusing merge with append
- Thinking delete+insert only adds rows
- Assuming truncate is an incremental strategy
Solution
Step 1: Identify correct config keys for incremental merge
dbt requires materialized='incremental' and incremental_strategy='merge' to use merge strategy.Step 2: Check each option for correctness
config(materialized='incremental', incremental_strategy='append') uses 'append' strategy, not merge; config(materialized='table', incremental_strategy='merge') uses materialized='table' which is not incremental; config(materialized='incremental', strategy='merge') uses wrong key 'strategy'.Final Answer:
config(materialized='incremental', incremental_strategy='merge') -> Option DQuick Check:
incremental_strategy='merge' with materialized='incremental' [OK]
- Using wrong materialized type
- Misspelling incremental_strategy key
- Confusing strategy key name
select id, value from source_table where updated_at > (select max(updated_at) from {{ this }})What will happen when this model runs?
Solution
Step 1: Understand the filter condition
The query selects rows from source_table where updated_at is greater than the max updated_at in the target table ({{ this }}).Step 2: Understand merge behavior
Merge updates existing rows with matching keys and inserts new rows. The filter ensures only changed rows are processed.Final Answer:
Rows with matching id are updated or inserted based on updated_at filter -> Option BQuick Check:
merge updates/inserts filtered rows [OK]
- Thinking it replaces entire table
- Assuming only new rows are appended
- Ignoring the filter condition effect
config(materialized='incremental', incremental_strategy='delete+insert') select * from source_table
But the model fails with an error about missing unique key. What is the likely cause?
Solution
Step 1: Recall delete+insert requirements
Delete+insert requires a unique_key config to identify rows to delete before insert.Step 2: Analyze error cause
Missing unique_key causes dbt to error because it cannot identify which rows to delete.Final Answer:
You did not specify the unique_key config required for delete+insert -> Option AQuick Check:
delete+insert needs unique_key [OK]
- Ignoring unique_key requirement
- Assuming delete+insert works without keys
- Confusing append with delete+insert
Solution
Step 1: Analyze data update needs
The table has new sales and corrections, so existing rows need updates and new rows need inserts.Step 2: Match strategy to needs
Append only adds new rows, so it won't update corrections. Delete+insert replaces matching rows but can be costly. Merge efficiently updates and inserts rows incrementally.Final Answer:
merge, because it updates existing rows and adds new ones -> Option AQuick Check:
merge = update + insert for corrections and new data [OK]
- Choosing append and missing updates
- Thinking delete+insert always best
- Ignoring performance of full refresh
Ready to prove it?
Pass the test and this pattern moves unknown
