| From: | Pavlo Golub <pavlo(dot)golub(at)cybertec(dot)at> |
|---|---|
| To: | Sami Imseih <samimseih(at)gmail(dot)com> |
| Cc: | Christoph Berg <myon(at)debian(dot)org>, Bertrand Drouvot <bertranddrouvot(dot)pg(at)gmail(dot)com>, "pgsql-hackers(at)lists(dot)postgresql(dot)org" <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
| Subject: | Re: [PATCH] Add last_executed timestamp to pg_stat_statements |
| Date: | 2026-02-16 19:00:32 |
| Message-ID: | CAK7ymc+0z7pL-Jub_52JDCyByxK3iYG7KHmudhsjgzF4WGmY0Q@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | 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 | Content-Type | Size |
|---|---|---|
| benchmark-raw-results.txt | text/plain | 669 bytes |
| v4-0001-pg_stat_statements-Add-stats_last_updated-column.patch | application/octet-stream | 18.1 KB |
| benchmark.sql | application/octet-stream | 1.5 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Tom Lane | 2026-02-16 19:01:38 | Re: Inconsistency in installation of syscache_info.h |
| Previous Message | Andres Freund | 2026-02-16 18:54:49 | Re: generating function default settings from pg_proc.dat |