Monitoring Performance

About Performance Views

There are several helpful performance views. The performance views display statistics that are gathered as your database is used. These views are helpful when a characteristic load has been applied to your database for a reasonable period.

Resetting the Data

You can reset the data in the performance views. To reset all statistics in the database:
SELECT pg_stat_reset();
To reset statistics for a single table:
SELECT pg_stat_reset_single_table_counters(oid);

Displaying the Cache Hit Ratio

The buffer cache hit ratio should be about 99%. If it is not, you might need to increase its size. To see the cache hit ratio for tables:
SELECT sum(heap_blks_read) as heap_blks_read, sum(heap_blks_hit) as heap_blks_hit, 
   (sum(heap_blks_hit) - sum(heap_blks_read)) / sum(heap_blks_hit) as hit_ratio 
FROM pg_statio_user_tables;
To see the cache hit ration for indexes:
SELECT sum(idx_blks_read) as idx_blks_read, sum(idx_blks_hit) as idx_blks_hit, 
   (sum(idx_blks_hit) - sum(idx_blks_read)) / sum(idx_blks_hit) as hit_ratio 
FROM pg_statio_user_indexes;

Finding Missing Indexes

For any table over several thousand rows, the percent of time the index is used to access it should typically be near 99%. To find the missing indexes:
SELECT relname, 100 * idx_scan / (seq_scan + idx_scan) percent_of_times_index_used, 
   n_live_tup rows_in_table 
FROM pg_stat_user_tables WHERE seq_scan + idx_scan > 0 ORDER BY n_live_tup DESC;

Showing How the Database Executes a Query

You can see whether a particular query does a sequential scan instead of using an index:
EXPLAIN ANALYZE SELECT * from my_table where filer_condition;
For details about reading EXPLAIN output, see http://www.postgresql.org/docs/9.2/interactive/using-explain.html.

Logging All Statements That Take More Than 100 Milliseconds

  1. Edit the postgresql.conf file.
  2. Update the values of the following configuration settings:
    log_min_duration_statement = 100 
    log_line_prefix = '%t [%p]: [%l-1] '
  3. Reload the server by issuing the pg_ctl reload command. A server reload does not terminate existing sessions, whereas a restart does.
  4. Run a characteristic load to generate information in the log.
    • To log fewer statements, increase the value of log_min_duration_statement.
    • To log all statements, set the value to 0.
    • To turn off logging, set the value to -1.
    You can view the log manually or use a tool like pgBadger. For more information about pgBadger, see http://dalibo.github.com/pgbadger/.

Seeing All Indexes in Your Tables

To see the indexes in your tables:
SELECT n.nspname as "Schema" , t.relname as "Table",c.relname as "Index"
FROM pg_catalog.pg_class c
   JOIN pg_catalog.pg_namespace n on n.oid = c.relnamespace
   JOIN pg_catalog.pg_index i on i.indexrelid = c.oid
   JOIN pg_catalog.pg_class t on i.indrelid = t.oid
WHERE c.relkind = 'i' and n.nspname not in ('pg_catalog', 'pg_toast') and 
   pg_catalog.pg_table_is_visible(c.oid)
ORDER BY n.nspname,t.relname,c.relname;

Determining the Last Time Vacuum and Analyze Were Run

Vacuuming removes rows marked for delete and analyze updates the statistics on the table used by the query optimizer. These operations should be run automatically at appropriate times. If any index is not being used, or you observe unusual slowness, you should check that they have been run recently.
SELECT relname, last_vacuum, last_autovacuum, last_analyze, last_autoanalyze
FROM pg_stat_user_tables ORDER BY relname;

Identifying Currently Running Queries

To see how long a query has been running:
SELECT procpid, current_timestamp - xact_start AS xact_runtime, current_query
FROM pg_stat_activity where xact_start is not null 
ORDER BY xact_start;
To see the most common currently running queries:
SELECT count(*) as cnt, current_query FROM pg_stat_activity 
GROUP BY current_query 
ORDER BY cnt DESC;