Row-level vs statement-level triggers in PostgreSQL - Performance Comparison
Start learning this pattern below
Jump into concepts and practice - no test required
When using triggers in PostgreSQL, it's important to know how their execution time changes as more rows are affected.
We want to understand how row-level and statement-level triggers behave as input size grows.
Analyze the time complexity of these two trigger types.
-- Row-level trigger example
CREATE FUNCTION trg_row_func() RETURNS trigger AS $$
BEGIN
-- some operation per row
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trg_row AFTER INSERT ON my_table
FOR EACH ROW EXECUTE FUNCTION trg_row_func();
-- Statement-level trigger example
CREATE FUNCTION trg_stmt_func() RETURNS trigger AS $$
BEGIN
-- some operation once per statement
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trg_stmt AFTER INSERT ON my_table
FOR EACH STATEMENT EXECUTE FUNCTION trg_stmt_func();
The first trigger runs once for every inserted row; the second runs once per insert statement regardless of rows.
Look at how often the trigger function runs.
- Primary operation: Trigger function execution
- How many times: Row-level: once per row; Statement-level: once per statement
As the number of inserted rows increases, the row-level trigger runs more times, but the statement-level trigger runs only once.
| Input Size (rows inserted) | Row-level Trigger Calls | Statement-level Trigger Calls |
|---|---|---|
| 10 | 10 | 1 |
| 100 | 100 | 1 |
| 1000 | 1000 | 1 |
Pattern observation: Row-level trigger calls grow linearly with rows; statement-level trigger calls stay constant.
Time Complexity: O(n) for row-level triggers, O(1) for statement-level triggers
This means row-level triggers take more time as more rows are affected, while statement-level triggers take about the same time no matter how many rows.
[X] Wrong: "Row-level and statement-level triggers run the same number of times for an insert."
[OK] Correct: Row-level triggers run once per row, so their work grows with rows. Statement-level triggers run once per statement, so their work stays the same regardless of rows.
Understanding how triggers scale helps you design efficient database logic and shows you can think about performance as data grows.
What if we changed a row-level trigger to a statement-level trigger? How would the time complexity change when inserting many rows?
Practice
Solution
Step 1: Understand trigger execution scope
Row-level triggers run once for every row affected by the SQL command, meaning if 10 rows are updated, the trigger runs 10 times.Step 2: Understand statement-level trigger behavior
Statement-level triggers run only once per SQL command, regardless of how many rows are affected.Final Answer:
Row-level triggers execute once for each affected row; statement-level triggers execute once per SQL statement. -> Option CQuick Check:
Row-level = per row, Statement-level = per statement [OK]
- Confusing which trigger runs per row vs per statement
- Thinking row-level triggers run only once per statement
- Assuming statement-level triggers run per row
- Believing trigger types depend on operation type (INSERT/UPDATE)
Solution
Step 1: Identify correct trigger syntax
The syntax for creating a row-level trigger requires the clause FOR EACH ROW to specify it runs per affected row.Step 2: Check full syntax correctness
CREATE TRIGGER trg AFTER INSERT ON table FOR EACH ROW EXECUTE FUNCTION func(); correctly includes AFTER INSERT, ON table, FOR EACH ROW, and EXECUTE FUNCTION func(); which is the proper syntax.Final Answer:
CREATE TRIGGER trg AFTER INSERT ON table FOR EACH ROW EXECUTE FUNCTION func(); -> Option AQuick Check:
Row-level triggers use FOR EACH ROW [OK]
- Omitting FOR EACH ROW for row-level triggers
- Using FOR EACH STATEMENT for row-level triggers
- Missing EXECUTE FUNCTION keyword
- Incorrect order of clauses
CREATE FUNCTION trg_func() RETURNS trigger AS $$ BEGIN RAISE NOTICE 'Triggered'; RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE TRIGGER trg AFTER UPDATE ON employees FOR EACH ROW EXECUTE FUNCTION trg_func(); UPDATE employees SET salary = salary * 1.1 WHERE department = 'Sales';What will be the output when the UPDATE affects 3 rows?
Solution
Step 1: Identify trigger type and execution count
The trigger is defined FOR EACH ROW, so it runs once for every row updated.Step 2: Calculate total trigger executions
Since 3 rows are updated, the trigger function runs 3 times, each raising the notice 'Triggered'.Final Answer:
The notice 'Triggered' will appear 3 times. -> Option AQuick Check:
Row-level trigger runs per row = 3 notices [OK]
- Assuming notice appears only once per statement
- Confusing FOR EACH ROW with FOR EACH STATEMENT
- Thinking AFTER UPDATE triggers don't raise notices
- Believing trigger runs multiple times per row
Solution
Step 1: Understand trigger definition impact
If a trigger runs multiple times per row update, it is likely defined as FOR EACH ROW, not FOR EACH STATEMENT.Step 2: Verify PostgreSQL trigger capabilities
PostgreSQL supports both row-level and statement-level triggers; statement-level triggers run once per statement.Final Answer:
You accidentally defined the trigger as FOR EACH ROW instead of FOR EACH STATEMENT. -> Option DQuick Check:
FOR EACH ROW triggers run per row, causing multiple executions [OK]
- Believing statement-level triggers run per row
- Ignoring trigger definition syntax
- Assuming PostgreSQL lacks statement-level triggers
- Blaming trigger function code without checking trigger type
Solution
Step 1: Determine trigger timing for logging after update
Logging after the update completes requires an AFTER trigger.Step 2: Choose trigger level for single summary message
To log once per statement regardless of rows, use a statement-level trigger (FOR EACH STATEMENT).Final Answer:
An AFTER UPDATE statement-level trigger -> Option BQuick Check:
Summary logging = AFTER + statement-level trigger [OK]
- Using row-level triggers causing multiple logs
- Using BEFORE triggers missing final state
- Confusing timing and level for logging
- Assuming row-level triggers can log once per statement
