{"id":243556,"date":"2025-12-18T20:15:20","date_gmt":"2025-12-19T03:15:20","guid":{"rendered":"https:\/\/virtual-dba.com\/?p=243556"},"modified":"2026-01-12T17:07:15","modified_gmt":"2026-01-13T00:07:15","slug":"mastering-pgstatstatements-in-postgresql","status":"publish","type":"post","link":"https:\/\/virtual-dba.com\/blog\/mastering-pgstatstatements-in-postgresql\/","title":{"rendered":"Mastering pg_stat_statements in PostgreSQL: A Complete Deep Dive with Practical Use Cases"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\" id=\"h-summary\">Summary<\/h2>\n\n\n\n<p>The <strong>pg_stat_statements<\/strong> extension <span style=\"box-sizing: border-box; margin: 0px; padding: 0px;\">is th<\/span>e definitive tool for\u00a0PostgreSQL\u00a0observability, enabling database administrators to pinpoint performance bottlenecks by aggregating detailed execution statistics\u2014such as CPU usage, I\/O latency, and query frequency\u2014for every unique SQL statement executed on the server.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Query Normalization:<\/strong> The extension replaces literal values in SQL statements with placeholders to track aggregated metrics for unique query patterns, allowing teams to identify systemic issues rather than one-off outliers.<\/li>\n\n\n\n<li><strong>Actionable Diagnostics:<\/strong> Administrators can run specific queries against the <strong>pg_stat_statements<\/strong> view to instantly isolate the top consumers of total execution time, detect &#8220;N+1&#8221; query loops, and identify statements causing heavy disk reads or WAL writes.<\/li>\n\n\n\n<li><strong>Configuration Requirements:<\/strong> Successful implementation requires adding the extension to <strong>shared_preload_libraries<\/strong> in the <code>postgresql.conf<\/code> file and restarting the server to ensure statistics are correctly loaded into shared memory.<\/li>\n\n\n\n<li><strong>Advanced Capabilities:<\/strong> Beyond basic execution times, the tool can be configured to track query planning duration and utility commands, providing critical insights into planner misestimations and maintenance overhead.<\/li>\n<\/ul>\n\n\n\n<p>Integrating this extension into standard monitoring routines empowers organizations to replace performance guesswork with data-driven optimization, directly improving application responsiveness and resource efficiency.<\/p>\n\n\n\n<div class=\"wp-block-yoast-seo-table-of-contents yoast-table-of-contents\"><h2>Table of contents<\/h2><ul><li><a href=\"#h-summary\" data-level=\"2\">Summary<\/a><\/li><li><a href=\"#h-introduction\" data-level=\"2\">Introduction<\/a><\/li><li><a href=\"#h-1-what-is-pg-stat-statements\" data-level=\"2\">1. What is pg_stat_statements<\/a><\/li><li><a href=\"#h-2-how-pg-stat-statements-works-internally\" data-level=\"2\">2. How pg_stat_statements Works Internally<\/a><ul><li><a href=\"#h-2-1-query-normalization\" data-level=\"3\">2.1 Query Normalization<\/a><\/li><li><a href=\"#h-2-2-tracking-metrics\" data-level=\"3\">2.2 Tracking Metrics<\/a><\/li><li><a href=\"#h-2-3-storage\" data-level=\"3\">2.3 Storage<\/a><\/li><\/ul><\/li><li><a href=\"#h-3-how-to-enable-pg-stat-statements\" data-level=\"2\">3. How to Enable pg_stat_statements<\/a><ul><li><a href=\"#h-3-1-modify-postgresql-conf\" data-level=\"3\">3.1 Modify postgresql.conf<\/a><\/li><li><a href=\"#h-3-2-restart-postgresql\" data-level=\"3\">3.2 Restart PostgreSQL<\/a><\/li><li><a href=\"#h-3-3-create-the-extension\" data-level=\"3\">3.3 Create the Extension<\/a><\/li><\/ul><\/li><li><a href=\"#h-4-exploring-pg-stat-statements-columns\" data-level=\"2\">4. Exploring pg_stat_statements Columns<\/a><\/li><li><a href=\"#h-5-real-world-use-cases\" data-level=\"2\">5. Real World Use Cases<\/a><ul><li><a href=\"#h-5-1-identify-slow-queries\" data-level=\"3\">5.1 Identify Slow Queries<\/a><\/li><li><a href=\"#h-5-2-identify-queries-with-high-total-time\" data-level=\"3\">5.2 Identify Queries with High Total Time<\/a><\/li><li><a href=\"#h-5-3-find-queries-causing-heavy-i-o\" data-level=\"3\">5.3 Find Queries Causing Heavy I\/O<\/a><\/li><li><a href=\"#h-5-4-find-queries-with-high-wal-writes\" data-level=\"3\">5.4 Find Queries with High WAL Writes<\/a><\/li><li><a href=\"#h-5-5-detect-n-plus-one-query-issues\" data-level=\"3\">5.5 Detect N Plus One Query Issues<\/a><\/li><li><a href=\"#h-5-6-compare-before-and-after-changes\" data-level=\"3\">5.6 Compare Before and After Changes<\/a><\/li><li><a href=\"#h-5-7-real-world-example-from-a-client-engagement\" data-level=\"3\">5.7 Real World Example from a Client Engagement<\/a><\/li><\/ul><\/li><li><a href=\"#h-6-advanced-features\" data-level=\"2\">6. Advanced Features<\/a><ul><li><a href=\"#h-6-1-tracking-planning-time\" data-level=\"3\">6.1 Tracking Planning Time<\/a><\/li><li><a href=\"#h-6-2-track-utility-commands\" data-level=\"3\">6.2 Track Utility Commands<\/a><\/li><li><a href=\"#h-6-3-identifying-high-memory-sorts\" data-level=\"3\">6.3 Identifying High Memory Sorts<\/a><\/li><\/ul><\/li><li><a href=\"#h-7-when-not-to-use-pg-stat-statements\" data-level=\"2\">7. When Not to Use pg_stat_statements<\/a><\/li><li><a href=\"#h-8-tuning-parameters\" data-level=\"2\">8. Tuning Parameters<\/a><ul><li><a href=\"#h-8-1-pg-stat-statements-max\" data-level=\"3\">8.1 pg_stat_statements.max<\/a><\/li><li><a href=\"#h-8-2-pg-stat-statements-track\" data-level=\"3\">8.2 pg_stat_statements.track<\/a><\/li><li><a href=\"#h-8-3-pg-stat-statements-save\" data-level=\"3\">8.3 pg_stat_statements.save<\/a><\/li><\/ul><\/li><li><a href=\"#h-9-best-practices\" data-level=\"2\">9. Best Practices<\/a><\/li><li><a href=\"#h-10-conclusion\" data-level=\"2\">10. Conclusion<\/a><\/li><\/ul><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-introduction\">Introduction<\/h2>\n\n\n\n<p>Performance tuning in PostgreSQL becomes much easier when you have visibility into how your queries behave over time. One of the most powerful tools for this purpose is pg_stat_statements. It provides a clear picture of query execution patterns, resource consumption, and performance bottlenecks. This extension is part of the contrib module and is widely used by DBAs and application teams.<\/p>\n\n\n\n<p>This blog explains what pg_stat_statements is, how it works, how to enable it, and how to use it in real-world scenarios. It also covers tuning parameters, internal mechanics, limitations, and advanced tips.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-1-what-is-pg-stat-statements\">1. What is pg_stat_statements<\/h2>\n\n\n\n<p>pg_stat_statements is a PostgreSQL extension that tracks statistics for all SQL statements executed by the server. It normalizes queries by removing literal values and aggregates execution statistics for each unique normalized query.<\/p>\n\n\n\n<p>It helps you answer questions such as:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Which queries are slow<\/li>\n\n\n\n<li>Which queries are executed most frequently<\/li>\n\n\n\n<li>Which queries consume the most CPU time<\/li>\n\n\n\n<li>Which queries cause the most I\/O<\/li>\n\n\n\n<li>Which queries need indexing<\/li>\n\n\n\n<li>How performance changes after a code release or schema change<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-2-how-pg-stat-statements-works-internally\">2. How pg_stat_statements Works Internally<\/h2>\n\n\n\n<p>Understanding how it collects and aggregates data is crucial.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-2-1-query-normalization\">2.1 Query Normalization<\/h3>\n\n\n\n<p>Literal values are replaced with placeholders.<\/p>\n\n\n\n<p>Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">SELECT<\/mark> * <mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">FROM<\/mark> orders <mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">WHERE<\/mark> id = <mark style=\"background-color:rgba(0, 0, 0, 0);color:#c5221f\" class=\"has-inline-color\">101<\/mark>\n<mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">SELECT<\/mark> * <mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">FROM<\/mark> orders <mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">WHERE<\/mark> id = <mark style=\"background-color:rgba(0, 0, 0, 0);color:#c5221f\" class=\"has-inline-color\">202<\/mark><\/code><\/pre>\n\n\n\n<p>Both are stored as:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">SELECT<\/mark> * <mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">FROM<\/mark> orders <mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">WHERE<\/mark> id = $<mark style=\"background-color:rgba(0, 0, 0, 0);color:#c5221f\" class=\"has-inline-color\">1<\/mark><\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-2-2-tracking-metrics\">2.2 Tracking Metrics<\/h3>\n\n\n\n<p>For every normalized query, the extension tracks metrics such as:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Total execution time<\/li>\n\n\n\n<li>Average execution time<\/li>\n\n\n\n<li>Number of calls<\/li>\n\n\n\n<li>Min and max time<\/li>\n\n\n\n<li>Rows returned<\/li>\n\n\n\n<li>Rows processed<\/li>\n\n\n\n<li>Shared and local block hits or reads<\/li>\n\n\n\n<li>Temp reads or writes<\/li>\n\n\n\n<li>I\/O time breakdown<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-2-3-storage\">2.3 Storage<\/h3>\n\n\n\n<p>Data is stored in shared memory. When the server restarts, the stats are retained if track_activity_query_size and shared_preload_libraries are set correctly.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-3-how-to-enable-pg-stat-statements\">3. How to Enable pg_stat_statements<\/h2>\n\n\n\n<p>This extension requires a parameter added to shared_preload_libraries because it must be loaded at server start.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-3-1-modify-postgresql-conf\">3.1 Modify postgresql.conf<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>shared_preload_libraries = '<mark style=\"background-color:rgba(0, 0, 0, 0);color:#188038\" class=\"has-inline-color\">pg_stat_statements<\/mark>'\npg_stat_statements.max = <mark style=\"background-color:rgba(0, 0, 0, 0);color:#c5221f\" class=\"has-inline-color\">10000<\/mark>\npg_stat_statements.track = all\npg_stat_statements.track_utility = off\npg_stat_statements.save = on\npg_stat_statements.track_planning = on<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-3-2-restart-postgresql\">3.2 Restart PostgreSQL<\/h3>\n\n\n\n<p>You must restart the service because <strong>shared_preload_libraries <\/strong>is involved.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-3-3-create-the-extension\">3.3 Create the Extension<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code><mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">CREATE<\/mark> EXTENSION pg_stat_statements;<\/code><\/pre>\n\n\n\n<p>You can now query the pg_stat_statements view.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-4-exploring-pg-stat-statements-columns\">4. Exploring pg_stat_statements Columns<\/h2>\n\n\n\n<p>Important columns include:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><strong>Column<\/strong><\/td><td><strong>Explanation<\/strong><\/td><\/tr><tr><td>query<\/td><td>Normalized statement text<\/td><\/tr><tr><td>calls<\/td><td>Number of times the query was executed<\/td><\/tr><tr><td>total_time<\/td><td>Sum of execution time in milliseconds<\/td><\/tr><tr><td>mean_time<\/td><td>Average time per call<\/td><\/tr><tr><td>min_time and max_time<\/td><td>Fastest and slowest execution<\/td><\/tr><tr><td>rows<\/td><td>Rows returned or affected<\/td><\/tr><tr><td>shared_blks_hit<\/td><td>Blocks found in shared buffers<\/td><\/tr><tr><td>shared_blks_read<\/td><td>Blocks read from disk<\/td><\/tr><tr><td>temp_blks_written<\/td><td>Temp file writes used by sorts or hashes<\/td><\/tr><tr><td>local_blks_read and hit<\/td><td>Local buffer activity<\/td><\/tr><tr><td>wal_bytes<\/td><td>WAL data generated by the query<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>These metrics help pinpoint whether a query is slow due to CPU, I\/O, or plan issues.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-5-real-world-use-cases\">5. Real World Use Cases<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-5-1-identify-slow-queries\">5.1 Identify Slow Queries<\/h3>\n\n\n\n<p>To find your top slowest queries based on average execution time:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">SELECT<\/mark> query, mean_time, calls\n<mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">FROM<\/mark> pg_stat_statements\n<mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">ORDER BY<\/mark> mean_time <mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">DESC<\/mark>\n<mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">LIMIT<\/mark> <mark style=\"background-color:rgba(0, 0, 0, 0);color:#c5221f\" class=\"has-inline-color\">5<\/mark>;<\/code><\/pre>\n\n\n\n<p>This helps detect queries that take long per call.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-5-2-identify-queries-with-high-total-time\">5.2 Identify Queries with High Total Time<\/h3>\n\n\n\n<p>These queries consume the most server resources overall. They may run frequently or be inherently slow.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">SELECT<\/mark> query, total_time, calls\n<mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">FROM<\/mark> pg_stat_statements\n<mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">ORDER BY<\/mark> total_time <mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">DESC<\/mark>\n<mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">LIMIT<\/mark> <mark style=\"background-color:rgba(0, 0, 0, 0);color:#c5221f\" class=\"has-inline-color\">5<\/mark>;<\/code><\/pre>\n\n\n\n<p>This gives you the highest impact queries to tune.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-5-3-find-queries-causing-heavy-i-o\">5.3 Find Queries Causing Heavy I\/O<\/h3>\n\n\n\n<p>If your server has high disk activity, use this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">SELECT<\/mark> query,\n       shared_blks_read <mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">AS <\/mark>disk_reads,\n       shared_blks_hit,\n       calls\n<mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">FROM<\/mark> pg_stat_statements\n<mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">ORDER BY<\/mark> shared_blks_read <mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">DESC<\/mark>\n<mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">LIMIT<\/mark> <mark style=\"background-color:rgba(0, 0, 0, 0);color:#c5221f\" class=\"has-inline-color\">5<\/mark>;<\/code><\/pre>\n\n\n\n<p>These queries often need improvements in indexing or caching.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-5-4-find-queries-with-high-wal-writes\">5.4 Find Queries with High WAL Writes<\/h3>\n\n\n\n<p>Useful during performance degradation or when WAL volume spikes.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">SELECT<\/mark> query, wal_bytes\n<mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">FROM<\/mark> pg_stat_statements\n<mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">ORDER BY<\/mark> wal_bytes <mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">DESC<\/mark>\n<mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">LIMIT<\/mark> <mark style=\"background-color:rgba(0, 0, 0, 0);color:#c5221f\" class=\"has-inline-color\">5<\/mark>;<\/code><\/pre>\n\n\n\n<p>This helps identify heavy write operations such as large updates, deletes, or bulk inserts.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-5-5-detect-n-plus-one-query-issues\">5.5 Detect N Plus One Query Issues<\/h3>\n\n\n\n<p>If a query is executed too many times repeatedly, it may indicate application design issues.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">SELECT<\/mark> query, calls\n<mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">FROM<\/mark> pg_stat_statements\n<mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">ORDER BY<\/mark> calls <mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">DESC<\/mark>\n<mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">LIMIT<\/mark> <mark style=\"background-color:rgba(0, 0, 0, 0);color:#c5221f\" class=\"has-inline-color\">5<\/mark>;<\/code><\/pre>\n\n\n\n<p>If one simple query is called millions of times, it may require batching.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-5-6-compare-before-and-after-changes\">5.6 Compare Before and After Changes<\/h3>\n\n\n\n<p>After creating indexes or tuning configuration, reset stats:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">SELECT<\/mark> pg_stat_statements_reset();<\/code><\/pre>\n\n\n\n<p>Rerun the workload and compare results. This is very useful for performance testing.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-5-7-real-world-example-from-a-client-engagement\">5.7 Real World Example from a Client Engagement<\/h3>\n\n\n\n<p>A recent engagement clearly demonstrated the value of pg_stat_statements during active performance troubleshooting. During the assessment, we generated a list of the most CPU-intensive queries using the following statement.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">SELECT<\/mark>\n  query,\n  calls,\n  rows,\n  total_exec_time,\n  mean_exec_time,\n  to_char((total_exec_time \/ <mark style=\"background-color:rgba(0, 0, 0, 0);color:#c5221f\" class=\"has-inline-color\">1000<\/mark>) * interval <mark style=\"background-color:rgba(0, 0, 0, 0);color:#188038\" class=\"has-inline-color\">'1 second'<\/mark>, <mark style=\"background-color:rgba(0, 0, 0, 0);color:#188038\" class=\"has-inline-color\">'HH24:MI:SS'<\/mark>) <mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">AS<\/mark> total_time_hms,\n  to_char((mean_exec_time \/ <mark style=\"background-color:rgba(0, 0, 0, 0);color:#c5221f\" class=\"has-inline-color\">1000<\/mark>) * interval '<mark style=\"background-color:rgba(0, 0, 0, 0);color:#188038\" class=\"has-inline-color\">1 second'<\/mark>, <mark style=\"background-color:rgba(0, 0, 0, 0);color:#188038\" class=\"has-inline-color\">'MI:SS.MS'<\/mark>) <mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">AS<\/mark> avg_time_mss,\n  round((total_exec_time \/ sum(total_exec_time) <mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">OVER<\/mark> ())::numeric * <mark style=\"background-color:rgba(0, 0, 0, 0);color:#c5221f\" class=\"has-inline-color\">100<\/mark>, <mark style=\"background-color:rgba(0, 0, 0, 0);color:#c5221f\" class=\"has-inline-color\">2<\/mark>) || <mark style=\"background-color:rgba(0, 0, 0, 0);color:#188038\" class=\"has-inline-color\">'% of total load'<\/mark> <mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">AS<\/mark> pct_load\n<mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">FROM<\/mark>\n  pg_stat_statements\n<mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">WHERE<\/mark>\n  query <mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">NOT LIKE<\/mark> <mark style=\"background-color:rgba(0, 0, 0, 0);color:#188038\" class=\"has-inline-color\">'BEGIN%'<\/mark> <mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">AND<\/mark> query <mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">NOT LIKE<\/mark> <mark style=\"background-color:rgba(0, 0, 0, 0);color:#188038\" class=\"has-inline-color\">'COMMIT%'<\/mark> <mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">AND<\/mark> query <mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">NOT LIKE<\/mark> <mark style=\"background-color:rgba(0, 0, 0, 0);color:#188038\" class=\"has-inline-color\">'ROLLBACK%'<\/mark>\n<mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">ORDER BY<\/mark>\n  total_exec_time <mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">DESC<\/mark>\n<mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">LIMIT<\/mark> <mark style=\"background-color:rgba(0, 0, 0, 0);color:#c5221f\" class=\"has-inline-color\">15<\/mark>;<\/code><\/pre>\n\n\n\n<p>This helped us quickly identify several queries that were consuming a very high percentage of the total CPU load. Many of these statements were executed frequently and scanned large tables because the required indexes were missing. After reviewing the execution plans, we created the appropriate indexes and optimized a few filter conditions.<\/p>\n\n\n\n<p>Once these changes were deployed, the improvement was significant. CPU usage dropped, overall execution time decreased, and the application became noticeably faster for end users.<\/p>\n\n\n\n<p>This is a practical example of how pg_stat_statements provides clear, actionable insights and helps teams resolve real-world performance issues efficiently.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-6-advanced-features\">6. Advanced Features<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-6-1-tracking-planning-time\">6.1 Tracking Planning Time<\/h3>\n\n\n\n<p>With track_planning enabled, you get planning time in addition to execution time. This is extremely helpful when:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Your query takes long to plan<\/li>\n\n\n\n<li>The planner misestimates cardinality<\/li>\n\n\n\n<li>Statistics are outdated<\/li>\n<\/ul>\n\n\n\n<p>Columns include plan_time and execution_time.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-6-2-track-utility-commands\">6.2 Track Utility Commands<\/h3>\n\n\n\n<p>Utility commands include CREATE TABLE, DROP, VACUUM, and COPY.<\/p>\n\n\n\n<p>By default, track_utility is off. You can enable it to audit heavy operations.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-6-3-identifying-high-memory-sorts\">6.3 Identifying High Memory Sorts<\/h3>\n\n\n\n<p>Look for temp_blks_read and temp_blks_written. These indicate disk sorts or hashes.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">SELECT<\/mark> query, temp_blks_read, temp_blks_written\n<mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">FROM<\/mark> pg_stat_statements\n<mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">ORDER BY<\/mark> temp_blks_written <mark style=\"background-color:rgba(0, 0, 0, 0);color:#1967d2\" class=\"has-inline-color\">DESC<\/mark>;<\/code><\/pre>\n\n\n\n<p>If temp blocks are very high, you may need to increase work_mem, rewrite the query, or adjust indexing.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-7-when-not-to-use-pg-stat-statements\">7. When Not to Use pg_stat_statements<\/h2>\n\n\n\n<p>Although powerful, pg_stat_statements can be used carefully in some cases.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Extremely high-volume OLTP systems may generate overhead<\/li>\n\n\n\n<li>Very large pg_stat_statements.max can increase shared memory usage<\/li>\n\n\n\n<li>Literal removal means that different parameter values appear identical in stats<\/li>\n\n\n\n<li>Query text is truncated based on track_activity_query_size<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-8-tuning-parameters\">8. Tuning Parameters<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-8-1-pg-stat-statements-max\">8.1 pg_stat_statements.max<\/h3>\n\n\n\n<p>Defines the number of unique normalized statements stored. Increase if you have many unique queries.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-8-2-pg-stat-statements-track\">8.2 pg_stat_statements.track<\/h3>\n\n\n\n<p>Options include all, top, or none. Use all for maximum visibility.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-8-3-pg-stat-statements-save\">8.3 pg_stat_statements.save<\/h3>\n\n\n\n<p>Keeps stats across restarts. This is useful for long-term continuous monitoring.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-9-best-practices\">9. Best Practices<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Reset stats before running benchmarking tools such as pgbench<\/li>\n\n\n\n<li>Periodically export results for trend analysis<\/li>\n\n\n\n<li>Combine pg_stat_statements with analysis of autovacuum logs for deeper tuning.<\/li>\n\n\n\n<li>Do not keep pg_stat_statements.max too low<\/li>\n\n\n\n<li>Use track_planning for diagnosing planner bottlenecks<\/li>\n\n\n\n<li>Always analyze slow queries with EXPLAIN and EXPLAIN ANALYZE<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-10-conclusion\">10. Conclusion<\/h2>\n\n\n\n<p><strong>pg_stat_statements <\/strong>is one of the most valuable performance tuning tools in PostgreSQL. It allows DBAs and developers to identify problematic queries, compare performance changes, reduce I\/O, and diagnose inefficiencies. By understanding its metrics and applying them to real-world use cases, you can optimize workloads and maintain high performance across environments.<\/p>\n\n\n\n<p><strong>For any questions, please contact us.<\/strong><\/p>\n\n\n\n<p><a href=\"http:\/\/virtual-dba.com\/platforms\/postgresql\/\">Get 24\/7 PostgreSQL Support and Managed Services with Certified Experts from XTIVIA Virtual-DBA 24\/7. <\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary The pg_stat_statements extension is the definitive tool for\u00a0PostgreSQL\u00a0observability, enabling database administrators to pinpoint performance bottlenecks by aggregating detailed execution statistics\u2014such as CPU usage, I\/O latency, and query frequency\u2014for every unique SQL statement executed on the server. Integrating this extension into standard monitoring routines empowers organizations to replace performance guesswork with data-driven optimization, directly improving [&hellip;]<\/p>\n","protected":false},"author":75,"featured_media":243590,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"off","_et_pb_old_content":"<!-- wp:heading -->\n<h2 class=\"wp-block-heading\" id=\"h-summary\">Summary<\/h2>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>This blog is a complete guide to\u00a0<strong>pg_stat_statements<\/strong>, showing how to use its metrics to find slow queries and optimize PostgreSQL performance.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:yoast-seo\/table-of-contents -->\n<div class=\"wp-block-yoast-seo-table-of-contents yoast-table-of-contents\"><h2>Table of contents<\/h2><ul><li><a href=\"#h-summary\" data-level=\"2\">Summary<\/a><\/li><li><a href=\"#h-1-what-is-pg-stat-statements\" data-level=\"2\">1. What is pg_stat_statements<\/a><\/li><\/ul><\/div>\n<!-- \/wp:yoast-seo\/table-of-contents -->\n\n<!-- wp:paragraph -->\n<p>Performance tuning in PostgreSQL becomes much easier when you have visibility into how your queries behave over time. One of the most powerful tools for this purpose is pg_stat_statements. It provides a clear picture of query execution patterns, resource consumption, and performance bottlenecks. This extension is part of the contrib module and is widely used by DBAs and application teams.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>This blog explains what pg_stat_statements is, how it works, how to enable it, and how to use it in real-world scenarios. It also covers tuning parameters, internal mechanics, limitations, and advanced tips.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:heading -->\n<h2 class=\"wp-block-heading\" id=\"h-1-what-is-pg-stat-statements\">1. What is pg_stat_statements<\/h2>\n<!-- \/wp:heading -->\n\n<!-- wp:paragraph -->\n<p>pg_stat_statements is a PostgreSQL extension that tracks statistics for all SQL statements executed by the server. It normalizes queries by removing literal values and aggregates execution statistics for each unique normalized query.<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>It helps you answer questions such as:<\/p>\n<!-- \/wp:paragraph -->\n\n<!-- wp:list -->\n<ul class=\"wp-block-list\"><!-- wp:list-item -->\n<li>Which queries are slow<\/li>\n<!-- \/wp:list-item -->\n\n<!-- wp:list-item -->\n<li>Which queries are executed most frequently<\/li>\n<!-- \/wp:list-item -->\n\n<!-- wp:list-item -->\n<li>Which queries consume the most CPU time<\/li>\n<!-- \/wp:list-item -->\n\n<!-- wp:list-item -->\n<li>Which queries cause the most I\/O<\/li>\n<!-- \/wp:list-item -->\n\n<!-- wp:list-item -->\n<li>Which queries need indexing<\/li>\n<!-- \/wp:list-item -->\n\n<!-- wp:list-item -->\n<li>How performance changes after a code release or schema change<\/li>\n<!-- \/wp:list-item --><\/ul>\n<!-- \/wp:list -->","_et_gb_content_width":"","content-type":"","footnotes":""},"categories":[4166,2163],"tags":[4204,2166],"class_list":["post-243556","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog","category-postgresql","tag-database","tag-postgresql"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.1 (Yoast SEO v27.1.1) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Mastering pg_stat_statements in PostgreSQL | Virtual-DBA<\/title>\n<meta name=\"description\" content=\"Master PostgreSQL performance tuning with pg_stat_statements. Discover metrics that help identify slow queries and bottlenecks.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/virtual-dba.com\/blog\/mastering-pgstatstatements-in-postgresql\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Mastering pg_stat_statements in PostgreSQL: A Complete Deep Dive with Practical Use Cases\" \/>\n<meta property=\"og:description\" content=\"Master PostgreSQL performance tuning with pg_stat_statements. Discover metrics that help identify slow queries and bottlenecks.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/virtual-dba.com\/blog\/mastering-pgstatstatements-in-postgresql\/\" \/>\n<meta property=\"og:site_name\" content=\"Virtual-DBA Remote DBA Services &amp; Support - Certified Database Experts\" \/>\n<meta property=\"article:published_time\" content=\"2025-12-19T03:15:20+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-01-13T00:07:15+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/virtual-dba.com\/wp-content\/uploads\/Mastering-pg_stat_statements-in-PostgreSQL-A-Complete-Deep-Dive-with-Practical-Use-Cases.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"557\" \/>\n\t<meta property=\"og:image:height\" content=\"291\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Pratik Kumar Saha\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@virtual_dba\" \/>\n<meta name=\"twitter:site\" content=\"@virtual_dba\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Pratik Kumar Saha\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"TechArticle\",\"@id\":\"https:\/\/virtual-dba.com\/blog\/mastering-pgstatstatements-in-postgresql\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/virtual-dba.com\/blog\/mastering-pgstatstatements-in-postgresql\/\"},\"author\":{\"name\":\"Pratik Kumar Saha\",\"@id\":\"https:\/\/virtual-dba.com\/#\/schema\/person\/46c77c897d15559adb840fd54a94bf8b\"},\"headline\":\"Mastering pg_stat_statements in PostgreSQL: A Complete Deep Dive with Practical Use Cases\",\"datePublished\":\"2025-12-19T03:15:20+00:00\",\"dateModified\":\"2026-01-13T00:07:15+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/virtual-dba.com\/blog\/mastering-pgstatstatements-in-postgresql\/\"},\"wordCount\":1414,\"publisher\":{\"@id\":\"https:\/\/virtual-dba.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/virtual-dba.com\/blog\/mastering-pgstatstatements-in-postgresql\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/virtual-dba.com\/wp-content\/uploads\/Mastering-pg_stat_statements-in-PostgreSQL-A-Complete-Deep-Dive-with-Practical-Use-Cases.jpg\",\"keywords\":[\"database\",\"PostgreSQL\"],\"articleSection\":[\"Blog\",\"PostgreSQL\"],\"inLanguage\":\"en-US\",\"accessibilityFeature\":[\"tableOfContents\"]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/virtual-dba.com\/blog\/mastering-pgstatstatements-in-postgresql\/\",\"url\":\"https:\/\/virtual-dba.com\/blog\/mastering-pgstatstatements-in-postgresql\/\",\"name\":\"Mastering pg_stat_statements in PostgreSQL | Virtual-DBA\",\"isPartOf\":{\"@id\":\"https:\/\/virtual-dba.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/virtual-dba.com\/blog\/mastering-pgstatstatements-in-postgresql\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/virtual-dba.com\/blog\/mastering-pgstatstatements-in-postgresql\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/virtual-dba.com\/wp-content\/uploads\/Mastering-pg_stat_statements-in-PostgreSQL-A-Complete-Deep-Dive-with-Practical-Use-Cases.jpg\",\"datePublished\":\"2025-12-19T03:15:20+00:00\",\"dateModified\":\"2026-01-13T00:07:15+00:00\",\"description\":\"Master PostgreSQL performance tuning with pg_stat_statements. Discover metrics that help identify slow queries and bottlenecks.\",\"breadcrumb\":{\"@id\":\"https:\/\/virtual-dba.com\/blog\/mastering-pgstatstatements-in-postgresql\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/virtual-dba.com\/blog\/mastering-pgstatstatements-in-postgresql\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/virtual-dba.com\/blog\/mastering-pgstatstatements-in-postgresql\/#primaryimage\",\"url\":\"https:\/\/virtual-dba.com\/wp-content\/uploads\/Mastering-pg_stat_statements-in-PostgreSQL-A-Complete-Deep-Dive-with-Practical-Use-Cases.jpg\",\"contentUrl\":\"https:\/\/virtual-dba.com\/wp-content\/uploads\/Mastering-pg_stat_statements-in-PostgreSQL-A-Complete-Deep-Dive-with-Practical-Use-Cases.jpg\",\"width\":557,\"height\":291},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/virtual-dba.com\/blog\/mastering-pgstatstatements-in-postgresql\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/virtual-dba.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Mastering pg_stat_statements in PostgreSQL: A Complete Deep Dive with Practical Use Cases\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/virtual-dba.com\/#website\",\"url\":\"https:\/\/virtual-dba.com\/\",\"name\":\"Virtual-DBA Remote DBA Services &amp; Support - Certified Database Experts\",\"description\":\"Remote Database Administration\",\"publisher\":{\"@id\":\"https:\/\/virtual-dba.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/virtual-dba.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/virtual-dba.com\/#organization\",\"name\":\"Virtual-DBA: Remote DBA | Remote Database Administration\",\"alternateName\":\"Virtual-DBA powered by XTIVIA\",\"url\":\"https:\/\/virtual-dba.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/virtual-dba.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/virtual-dba.com\/wp-content\/uploads\/V-DBA-Database-Services-and-Support-Featured-Logo.jpg\",\"contentUrl\":\"https:\/\/virtual-dba.com\/wp-content\/uploads\/V-DBA-Database-Services-and-Support-Featured-Logo.jpg\",\"width\":557,\"height\":291,\"caption\":\"Virtual-DBA: Remote DBA | Remote Database Administration\"},\"image\":{\"@id\":\"https:\/\/virtual-dba.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/virtual_dba\",\"https:\/\/www.linkedin.com\/showcase\/36220649\/\",\"https:\/\/www.youtube.com\/channel\/UCx3AIeUQ2ziTLKZSJDZ-SEg\"],\"description\":\"Eliminate database downtime and spiraling costs with XTIVIA\u2019s Virtual-DBA. In today\u2019s always-on business world, gaps in 24x7 on-call DBA support, neglected maintenance and security, or a stretched team struggling with overwhelming workloads can lead to costly disruptions and threaten business continuity. XTIVIA\u2019s Virtual-DBA provides the immediate, expert database administration you need, exactly when you need it, ensuring optimal performance, ironclad security, and significant cost savings without the burden of expanding your in-house team. The goal of Virtual-DBA is to provide a cost-effective solution for organizations seeking to optimize the security, management, maintenance, availability, and performance of their critical business systems, whether self-managed or cloud-managed (e.g., AWS RDS, Azure SQL Database). We accomplish this through a comprehensive remote DBA service offering designed specifically to meet the Oracle\u00ae, DB2\u00ae, Informix\u00ae, MySQL\u2122, PostgreSQL\u00ae, MongoDB\u00ae, MariaDB, and Microsoft SQL Server\u00ae, CockroachDB, Databricks, AWS, and Azure needs of our clients.\",\"email\":\"info@xtivia.com\",\"telephone\":\"8886853101\",\"legalName\":\"XTIVIA, Inc\",\"foundingDate\":\"1992-05-01\",\"numberOfEmployees\":{\"@type\":\"QuantitativeValue\",\"minValue\":\"201\",\"maxValue\":\"500\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/virtual-dba.com\/#\/schema\/person\/46c77c897d15559adb840fd54a94bf8b\",\"name\":\"Pratik Kumar Saha\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/virtual-dba.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/dcc6bc570615ac468756a7a78b2855af334bf7a07bb694d5cb2d03c33bdf5d75?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/dcc6bc570615ac468756a7a78b2855af334bf7a07bb694d5cb2d03c33bdf5d75?s=96&d=mm&r=g\",\"caption\":\"Pratik Kumar Saha\"},\"url\":\"https:\/\/virtual-dba.com\/author\/pratik-kumar-saha\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Mastering pg_stat_statements in PostgreSQL | Virtual-DBA","description":"Master PostgreSQL performance tuning with pg_stat_statements. Discover metrics that help identify slow queries and bottlenecks.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/virtual-dba.com\/blog\/mastering-pgstatstatements-in-postgresql\/","og_locale":"en_US","og_type":"article","og_title":"Mastering pg_stat_statements in PostgreSQL: A Complete Deep Dive with Practical Use Cases","og_description":"Master PostgreSQL performance tuning with pg_stat_statements. Discover metrics that help identify slow queries and bottlenecks.","og_url":"https:\/\/virtual-dba.com\/blog\/mastering-pgstatstatements-in-postgresql\/","og_site_name":"Virtual-DBA Remote DBA Services &amp; Support - Certified Database Experts","article_published_time":"2025-12-19T03:15:20+00:00","article_modified_time":"2026-01-13T00:07:15+00:00","og_image":[{"width":557,"height":291,"url":"https:\/\/virtual-dba.com\/wp-content\/uploads\/Mastering-pg_stat_statements-in-PostgreSQL-A-Complete-Deep-Dive-with-Practical-Use-Cases.jpg","type":"image\/jpeg"}],"author":"Pratik Kumar Saha","twitter_card":"summary_large_image","twitter_creator":"@virtual_dba","twitter_site":"@virtual_dba","twitter_misc":{"Written by":"Pratik Kumar Saha","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"TechArticle","@id":"https:\/\/virtual-dba.com\/blog\/mastering-pgstatstatements-in-postgresql\/#article","isPartOf":{"@id":"https:\/\/virtual-dba.com\/blog\/mastering-pgstatstatements-in-postgresql\/"},"author":{"name":"Pratik Kumar Saha","@id":"https:\/\/virtual-dba.com\/#\/schema\/person\/46c77c897d15559adb840fd54a94bf8b"},"headline":"Mastering pg_stat_statements in PostgreSQL: A Complete Deep Dive with Practical Use Cases","datePublished":"2025-12-19T03:15:20+00:00","dateModified":"2026-01-13T00:07:15+00:00","mainEntityOfPage":{"@id":"https:\/\/virtual-dba.com\/blog\/mastering-pgstatstatements-in-postgresql\/"},"wordCount":1414,"publisher":{"@id":"https:\/\/virtual-dba.com\/#organization"},"image":{"@id":"https:\/\/virtual-dba.com\/blog\/mastering-pgstatstatements-in-postgresql\/#primaryimage"},"thumbnailUrl":"https:\/\/virtual-dba.com\/wp-content\/uploads\/Mastering-pg_stat_statements-in-PostgreSQL-A-Complete-Deep-Dive-with-Practical-Use-Cases.jpg","keywords":["database","PostgreSQL"],"articleSection":["Blog","PostgreSQL"],"inLanguage":"en-US","accessibilityFeature":["tableOfContents"]},{"@type":"WebPage","@id":"https:\/\/virtual-dba.com\/blog\/mastering-pgstatstatements-in-postgresql\/","url":"https:\/\/virtual-dba.com\/blog\/mastering-pgstatstatements-in-postgresql\/","name":"Mastering pg_stat_statements in PostgreSQL | Virtual-DBA","isPartOf":{"@id":"https:\/\/virtual-dba.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/virtual-dba.com\/blog\/mastering-pgstatstatements-in-postgresql\/#primaryimage"},"image":{"@id":"https:\/\/virtual-dba.com\/blog\/mastering-pgstatstatements-in-postgresql\/#primaryimage"},"thumbnailUrl":"https:\/\/virtual-dba.com\/wp-content\/uploads\/Mastering-pg_stat_statements-in-PostgreSQL-A-Complete-Deep-Dive-with-Practical-Use-Cases.jpg","datePublished":"2025-12-19T03:15:20+00:00","dateModified":"2026-01-13T00:07:15+00:00","description":"Master PostgreSQL performance tuning with pg_stat_statements. Discover metrics that help identify slow queries and bottlenecks.","breadcrumb":{"@id":"https:\/\/virtual-dba.com\/blog\/mastering-pgstatstatements-in-postgresql\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/virtual-dba.com\/blog\/mastering-pgstatstatements-in-postgresql\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/virtual-dba.com\/blog\/mastering-pgstatstatements-in-postgresql\/#primaryimage","url":"https:\/\/virtual-dba.com\/wp-content\/uploads\/Mastering-pg_stat_statements-in-PostgreSQL-A-Complete-Deep-Dive-with-Practical-Use-Cases.jpg","contentUrl":"https:\/\/virtual-dba.com\/wp-content\/uploads\/Mastering-pg_stat_statements-in-PostgreSQL-A-Complete-Deep-Dive-with-Practical-Use-Cases.jpg","width":557,"height":291},{"@type":"BreadcrumbList","@id":"https:\/\/virtual-dba.com\/blog\/mastering-pgstatstatements-in-postgresql\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/virtual-dba.com\/"},{"@type":"ListItem","position":2,"name":"Mastering pg_stat_statements in PostgreSQL: A Complete Deep Dive with Practical Use Cases"}]},{"@type":"WebSite","@id":"https:\/\/virtual-dba.com\/#website","url":"https:\/\/virtual-dba.com\/","name":"Virtual-DBA Remote DBA Services &amp; Support - Certified Database Experts","description":"Remote Database Administration","publisher":{"@id":"https:\/\/virtual-dba.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/virtual-dba.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/virtual-dba.com\/#organization","name":"Virtual-DBA: Remote DBA | Remote Database Administration","alternateName":"Virtual-DBA powered by XTIVIA","url":"https:\/\/virtual-dba.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/virtual-dba.com\/#\/schema\/logo\/image\/","url":"https:\/\/virtual-dba.com\/wp-content\/uploads\/V-DBA-Database-Services-and-Support-Featured-Logo.jpg","contentUrl":"https:\/\/virtual-dba.com\/wp-content\/uploads\/V-DBA-Database-Services-and-Support-Featured-Logo.jpg","width":557,"height":291,"caption":"Virtual-DBA: Remote DBA | Remote Database Administration"},"image":{"@id":"https:\/\/virtual-dba.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/virtual_dba","https:\/\/www.linkedin.com\/showcase\/36220649\/","https:\/\/www.youtube.com\/channel\/UCx3AIeUQ2ziTLKZSJDZ-SEg"],"description":"Eliminate database downtime and spiraling costs with XTIVIA\u2019s Virtual-DBA. In today\u2019s always-on business world, gaps in 24x7 on-call DBA support, neglected maintenance and security, or a stretched team struggling with overwhelming workloads can lead to costly disruptions and threaten business continuity. XTIVIA\u2019s Virtual-DBA provides the immediate, expert database administration you need, exactly when you need it, ensuring optimal performance, ironclad security, and significant cost savings without the burden of expanding your in-house team. The goal of Virtual-DBA is to provide a cost-effective solution for organizations seeking to optimize the security, management, maintenance, availability, and performance of their critical business systems, whether self-managed or cloud-managed (e.g., AWS RDS, Azure SQL Database). We accomplish this through a comprehensive remote DBA service offering designed specifically to meet the Oracle\u00ae, DB2\u00ae, Informix\u00ae, MySQL\u2122, PostgreSQL\u00ae, MongoDB\u00ae, MariaDB, and Microsoft SQL Server\u00ae, CockroachDB, Databricks, AWS, and Azure needs of our clients.","email":"info@xtivia.com","telephone":"8886853101","legalName":"XTIVIA, Inc","foundingDate":"1992-05-01","numberOfEmployees":{"@type":"QuantitativeValue","minValue":"201","maxValue":"500"}},{"@type":"Person","@id":"https:\/\/virtual-dba.com\/#\/schema\/person\/46c77c897d15559adb840fd54a94bf8b","name":"Pratik Kumar Saha","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/virtual-dba.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/dcc6bc570615ac468756a7a78b2855af334bf7a07bb694d5cb2d03c33bdf5d75?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/dcc6bc570615ac468756a7a78b2855af334bf7a07bb694d5cb2d03c33bdf5d75?s=96&d=mm&r=g","caption":"Pratik Kumar Saha"},"url":"https:\/\/virtual-dba.com\/author\/pratik-kumar-saha\/"}]}},"_links":{"self":[{"href":"https:\/\/virtual-dba.com\/wp-json\/wp\/v2\/posts\/243556","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/virtual-dba.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/virtual-dba.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/virtual-dba.com\/wp-json\/wp\/v2\/users\/75"}],"replies":[{"embeddable":true,"href":"https:\/\/virtual-dba.com\/wp-json\/wp\/v2\/comments?post=243556"}],"version-history":[{"count":0,"href":"https:\/\/virtual-dba.com\/wp-json\/wp\/v2\/posts\/243556\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/virtual-dba.com\/wp-json\/wp\/v2\/media\/243590"}],"wp:attachment":[{"href":"https:\/\/virtual-dba.com\/wp-json\/wp\/v2\/media?parent=243556"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/virtual-dba.com\/wp-json\/wp\/v2\/categories?post=243556"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/virtual-dba.com\/wp-json\/wp\/v2\/tags?post=243556"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}