Avoiding Unnecessarily Running Triggers in Postgres
In Postgres (or any relational db), triggers can be useful:
name | updated_at |
---|---|
The Great Gatsby | 2024-08-24 17:58:09.87828-04 |
name | updated_at |
---|---|
THE GREAT GATSBY | 2024-08-24 18:01:21.313217-04 |
But, they can also cause performance issues. To show this, we’re going to create a pyramid scheme.
Case Study: A Pyramid Scheme
- Each person must sell $100 of goods
- Each person will attempt to bring in other people.
We’ll define revenue
as how much one individual has sold, and referred_revenue
as how much anyone they’ve referred has sold. We’ll take it a step further though, and we’ll give you credit for anyone who’s been referred by someone you referred, and so on.
As the creator of the scheme, my revenue + referred_revenue
is the total revenue of the company. Everybody is referred by me, or by somebody referred by me.
Let’s express our pyramid scheme in a schema:
Now, let’s see it in action:
We can see referred_revenue
cascading up the pyramid:
Name | Revenue | Referred Revenue |
---|---|---|
me | 100.00 | 600.00 |
Stella | 100.00 | 200.00 |
Cornelius | 100.00 | 200.00 |
Rita | 100.00 | 0.00 |
Conrad | 100.00 | 0.00 |
Helmut | 100.00 | 0.00 |
Manfried | 100.00 | 0.00 |
This is a nice approach because it’s handling recursion for us.
The Problem
Now, let’s say Cornelius gets a million new recruits, but they haven’t sold anything yet.
That’s taking minutes to run… we can’t have that. Our pyramid scheme requires maximum efficiency!
Fortunately, we know they haven’t sold anything, so we don’t need to update anyone’s referred_revenue
. We have 2 options.
Solution 1: Disable the Trigger
That runs in seconds. We could’ve also disabled all triggers on the table:
Solution 2: Conditionally Run the Trigger
To do this we’ll need to create two triggers, one for insert
and one for update
- the logic in each when
condition will be different.
And now our new members can join the scheme.
Conclusion
Being so specific about when a trigger runs can seem unnecessary, but as the pyramid scheme example shows, triggers can basically block bulk operations.
In situations where a trigger needs to run a query, I’ve found them to be a main culprit of performance issues.
Wow! You read the whole thing. People who make it this far sometimes
want to receive emails when I post something new.
I also have an RSS feed.