Re: [PATCH] Add last_executed timestamp to pg_stat_statements - Mailing list pgsql-hackers

From Pavlo Golub
Subject Re: [PATCH] Add last_executed timestamp to pg_stat_statements
Date
Msg-id CAK7ymc+0z7pL-Jub_52JDCyByxK3iYG7KHmudhsjgzF4WGmY0Q@mail.gmail.com
Whole thread
In response to Re: [PATCH] Add last_executed timestamp to pg_stat_statements  (Sami Imseih <samimseih@gmail.com>)
Responses Re: [PATCH] Add last_executed timestamp to pg_stat_statements
List pgsql-hackers
Hi hackers,

This is v4 of the patch adding a stats_last_updated column to
pg_stat_statements.

The thread is somehow shifted to things that are not related to the
patch initial idea. I decided to return to the beginning.
I simplified the implementation to use GetCurrentTimestamp() directly
instead of calculating the timestamp from
GetCurrentStatementStartTimestamp() + total_time. The previous optimization was
premature, benchmark testing proves GetCurrentTimestamp() adds no
measurable overhead.

Test environment: Dockerized Linux x86_64 under Windows host (the
worst possible combination), PostgreSQL 19devel, gcc-14.2.0
Test: 1,000,000 iterations of PERFORM 1 (fastest possible statement)

Unpatched PostgreSQL:
  track='none' (baseline): 562.07ms average
  track='all' (tracking):  719.17ms average
  Overhead: 157.10ms (27.9%)

Patched PostgreSQL (with stats_last_updated):
  track='none' (baseline): 548.95ms average
  track='all' (tracking):  732.50ms average
  Overhead: 183.55ms (33.4%)

Direct comparison (what matters):
  Unpatched track='all': 719.17ms
  Patched track='all':   732.50ms
  Difference: +13.33ms (+1.85%)
  Per-statement: 13.33ms / 1,000,000 = 13 nanoseconds

The baseline comparison shows patched is actually faster (-13ms),
which is impossible.
This confirms the 13ms variance is a measurement noise, not real overhead.

Real-world impact for 100ms query is 0.000013% overhead

GetCurrentTimestamp() is the standard approach used throughout PostgreSQL for
monitoring features. The measured overhead of 13 nanoseconds per statement is
negligible for any realistic workload and well within measurement noise.

The implementation captures GetCurrentTimestamp() before acquiring the spinlock,
so no syscall occurs while holding the lock. This is simple, correct, and has
no measurable performance impact.

Changes from v2-v3:
- Simplified implementation to use GetCurrentTimestamp() directly
- Removed complex calculation with GetCurrentStatementStartTimestamp()
  and total_time computation (premature optimization)
- Added comprehensive benchmark testing (unpatched vs patched)
- Benchmark testing shows no measurable overhead (<2% in synthetic tests)
- Measured overhead: 13ns per statement (1.85% for 1M iteration test,
  negligible for real queries >0.1ms)

Changes from v1:
- Rename column from last_executed to stats_last_updated (Christoph Berg)
- Move timestamp from Counters struct to pgssEntry for better semantics
- Place column at end of view to match stats_since naming convention
- Fixed whitespace errors
- Moved tests to entry_timestamp.sql (Sami Imseih)
- Updated PGSS_FILE_HEADER to handle structure change


Patch, benchmark script and raw results are attached.

Best regards,
Pavlo Golub

Attachment

pgsql-hackers by date:

Previous
From: Andres Freund
Date:
Subject: Re: generating function default settings from pg_proc.dat
Next
From: Tom Lane
Date:
Subject: Re: Inconsistency in installation of syscache_info.h