We spend a lot of time at Crunchy Data helping people dig into the performance of their Postgres. If you're setting up a new Postgres database or already running on in production there are a number of very basic steps you can take that will save your tail in the future when it comes to investigating performance. Here is your guide that'll take less than 5 minutes to get in place. Future you will thank you for doing this today.
records and parameterizes queries, how long they run, how often and much more
for you. With
pg_stat_statements you can ask questions such as:
- Which ones have taken up the most amount of time cumulatively to execute
- Which ones are run the most frequently
- And how long on average they take to execute
To enable simply:
CREATE EXTENSION pg_stat_statements;
Postgres can auto-log queries into your standard logs that run over a specified amount of time. Postgres is capable of executing queries in milliseconds quite easily, so the threshold you pick here is important. You don't want to log all queries, but don't want only the single worst offender. For most web applications I tend to recommend 100 milliseconds or 1 second. Set this with:
ALTER DATABASE us SET log_min_duration_statement = '1s';
auto_explain to log the explain plan for slow queries. In addition to
logging slow queries this will get you an
EXPLAIN plan. You can feed that into
tools like despez EXPLAIN or
You can enable auto explain for your Postgres database by adding it to the
shared preload libraries:
ALTER SYSTEM SET session_preload_libraries = 'auto_explain'; SELECT pg_reload_conf();
Once you've enabled
you want to set your various config for it on what you want it to log. Here's a
reasonable config to start with which will log all queries over 2 seconds:
ALTER SYSTEM SET auto_explain.log_min_duration = 2000; ALTER SYSTEM SET auto_explain.log_analyze = on; ALTER SYSTEM SET auto_explain.log_triggers = on; ALTER SYSTEM SET auto_explain.log_nested_statements = on; SELECT pg_reload_conf();
Postgres can easily auto-kill long running queries, this can prevent other performance issues from backing up and causing customer impact. Any query that needs to run longer than your statement timeout you can explicitly change in the session or on a per database user basis.
ALTER DATABASE mydatabase SET statement_timeout = '30s';
There you have it, your checklist for preparing your Postgres for better performance troubleshooting.
- pg_stat_statments ✅
- log queries over 1s ✅
- log explain plan of queries over 2s ✅
- auto-kill queries over 30s ✅
And your Postgres will be 💯.
February 9, 2023 •More by this author