These are the oldest logging parameters PostgreSQL still ships, and the output looks it. Each is a boolean, off by default, superuser context, and each makes the backend call getrusage() before and after one stage of running a statement and write the difference to the log at LOG level. log_parser_stats covers the parser, parse analysis, and the rewriter (three blocks per statement, one per stage); log_planner_stats covers the planner; log_executor_stats covers the executor; and log_statement_stats covers the whole statement, which is why it refuses to be enabled alongside any of the other three and they refuse to be enabled alongside it. The output for one SELECT count(*) with log_statement_stats on:
1 LOG: QUERY STATISTICS
2 DETAIL: ! system usage stats:
3 ! 0.178254 s user, 0.318332 s system, 5.021073 s elapsed
4 ! [0.179736 s user, 0.318332 s system total]
5 ! 126332 kB max resident size
6 ! 784/248560 [784/248560] filesystem blocks in/out
7 ! 0/2605 [0/3105] page faults/reclaims, 0 [0] swaps
8 ! 0 [0] signals rcvd, 0/0 [0/0] messages rcvd/sent
9 ! 270/281 [272/282] voluntary/involuntary context switches
10 STATEMENT: select count(*) from t
The unbracketed numbers are the delta for the stage; the bracketed ones are the backend’s totals since it started; max resident size is neither, being a high-water mark. The docs call this “a crude profiling instrument,” which is fair. It is getrusage() with a printf() around it, in a function that still carries a source comment about who drinks coffee at DEC, which dates it about as well as anything could.
The names are from 7.4, in 2003, when the show_*_stats family was renamed along with the rest of the logging parameters; the mechanism is older than EXPLAIN ANALYZE (7.2) and a good deal older than pg_stat_statements and auto_explain (both 8.4). That puts them in the family with array_nulls, backslash_quote, and bonjour: still present because removing a parameter breaks someone’s postgresql.conf, and the source says so, calling them legacy settings with little production usage in the comment over the hook that enforces the mutual exclusion. The same comment admits the exclusion does not quite work when the values arrive through ALTER ROLE ... SET. Nobody has cared enough to fix it, which is the vestigial condition in one sentence.
They are not quite useless, though, and this is where they differ from bonjour. They report things nothing else in core reports per statement: the user/system CPU split, page faults, context switches. EXPLAIN ANALYZE gives wall time and buffers; pg_stat_statements gives wall time and buffers, aggregated. Neither will tell you that the five seconds above were half a second of CPU and four and a half of waiting, or that a query is churning minor faults because something is allocating and freeing a large work_mem in a loop. If you need exactly that, for one query, SET log_executor_stats = on in a superuser session, run it, and set it back off; the answer is in the log.
Three things to know before believing the numbers. getrusage() is called for the backend alone, and parallel workers are separate processes, so a parallel query reports the leader’s share and nothing else; the same count(*) showed 0.03 s of user CPU with two workers and 0.12 s with none, and the smaller number is the wrong one. Every driver that uses the extended protocol (all of them) gets three blocks per statement, labeled PARSE MESSAGE, BIND MESSAGE, and EXECUTE MESSAGE STATISTICS, instead of one. And log_error_verbosity = terse strips the DETAIL, leaving a log of QUERY STATISTICS headings with nothing under them, which is a special kind of nothing.
If you want these counters for every query rather than one, that is pg_stat_kcache, which collects the same getrusage() fields and aggregates them by query ID alongside pg_stat_statements. It is what these four would be if they had been designed after 2009 instead of before 1997.
Leave all four off in postgresql.conf. Their habitat is a superuser session, for one statement, followed by SET back to off; anywhere else they produce a log made largely of exclamation marks.