Skip to content

Commit

Permalink
Add .psqlrc in dotfiles
Browse files Browse the repository at this point in the history
  • Loading branch information
marcwrobel committed Feb 8, 2025
1 parent 118e717 commit cbe5a75
Show file tree
Hide file tree
Showing 15 changed files with 252 additions and 0 deletions.
48 changes: 48 additions & 0 deletions dotfiles/.psqlrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
-- Official docs: http://www.postgresql.org/docs/9.3/static/app-psql.html
-- Unofficial docs: http://robots.thoughtbot.com/improving-the-command-line-postgres-experience

-- Prevent noisy loading of psqlrc file.
\set QUIET 1

-- Display NULL values as '[NULL]' instead of empty strings.
\pset null '[NULL]'

-- Improve prompt.
-- http://www.postgresql.org/docs/9.3/static/app-psql.html#APP-PSQL-PROMPTING
\set PROMPT1 '%[%033[1m%]%M %n@%/%R%[%033[0m%]%# '
\set PROMPT2 '[more] %R > '

-- Show how long each query takes to execute.
\timing

-- Use best available output format.
\x auto
\set VERBOSITY verbose
\set HISTFILE ~/.psql_history- :DBNAME
\set HISTCONTROL ignoredups

-- Some aliases to make life easier.
-- From https://github.com/baburdick/psqlrc-files
\set clear '\\! clear;'
\set sp 'SHOW search_path;'
\set uptime 'SELECT now() - pg_postmaster_start_time() AS uptime;'
\set settings 'SELECT name, setting, unit, context FROM pg_settings;'
\set conninfo 'SELECT usename, count(*) FROM pg_stat_activity GROUP BY usename;'
\set activity `cat ~/.psqlrc-aliases/activity.sql`
\set waits `cat ~/.psqlrc-aliases/waits.sql`
\set locks `cat ~/.psqlrc-aliases/locks.sql`
\set autovac_runtime `cat ~/.psqlrc-aliases/autovac_runtime.sql`
\set last_vacuum `cat ~/.psqlrc-aliases/last_vacuum_analyze.sql`
\set db_size `cat ~/.psqlrc-aliases/db_size.sql`
\set table_size `cat ~/.psqlrc-aliases/table_size.sql`
\set uselesscol `cat ~/.psqlrc-aliases/uselesscol.sql`
-- From https://gist.github.com/mculp/0533f938e04241cdd46c5ab531ada0ae
\set index_size `cat ~/.psqlrc-aliases/index_size.sql`
\set index_usage `cat ~/.psqlrc-aliases/index_usage.sql`
\set slow_queries `cat ~/.psqlrc-aliases/slow_queries.sql`
\set trash_indexes `cat ~/.psqlrc-aliases/trash_indexes.sql`
\set missing_indexes `cat ~/.psqlrc-aliases/missing_indexes.sql`
\set bloat `cat ~/.psqlrc-aliases/bloat.sql`

-- Set noisyness back to normal.
\unset QUIET
11 changes: 11 additions & 0 deletions dotfiles/.psqlrc_aliases/activity.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
-- Retrieves information about the current database connections and their activity from the pg_stat_activity.
SELECT datname,
pid,
usename,
application_name,
client_addr,
client_hostname,
client_port,
query,
state
FROM pg_stat_activity;
10 changes: 10 additions & 0 deletions dotfiles/.psqlrc_aliases/autovac_runtime.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
-- Retrieves information about currently running VACUUM operations.
SELECT datname,
usename,
pid,
waiting,
CURRENT_TIMESTAMP - xact_start AS xact_runtime,
query
FROM pg_stat_activity
WHERE UPPER(query) LIKE '%VACUUM%'
ORDER BY xact_start;
50 changes: 50 additions & 0 deletions dotfiles/.psqlrc_aliases/bloat.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
-- Identifies table and index bloat.
SELECT tablename as table_name,
ROUND(CASE WHEN otta=0 THEN 0.0 ELSE sml.relpages/otta::numeric END, 1) AS table_bloat,
CASE WHEN relpages < otta THEN ''0'' ELSE pg_size_pretty((bs*(sml.relpages-otta)::bigint)::bigint) END AS table_waste,
iname as index_name,
ROUND(CASE WHEN iotta=0 OR ipages=0 THEN 0.0 ELSE ipages/iotta::numeric END,1) AS index_bloat,
CASE WHEN ipages < iotta THEN ''0'' ELSE pg_size_pretty((bs*(ipages-iotta))::bigint) END AS index_waste
FROM (
SELECT schemaname,
tablename,
cc.reltuples,
cc.relpages,
bs,
CEIL((cc.reltuples*((datahdr+ma- (CASE WHEN datahdr%ma=0 THEN ma ELSE datahdr%ma END))+nullhdr2+4))/(bs-20::float)) AS otta,
COALESCE(c2.relname ,''?'') AS iname,
COALESCE(c2.reltuples ,0) AS ituples,
COALESCE(c2.relpages ,0) AS ipages,
COALESCE(CEIL((c2.reltuples*(datahdr-12))/(bs-20::float)), 0) AS iotta
FROM (
SELECT ma,
s,
schemaname,
tablename,
(datawidth+(hdr+ma-(case when hdr%ma=0 THEN ma ELSE hdr%ma END)))::numeric AS datahdr,
(maxfracsum*(nullhdr+ma-(case when nullhdr%ma=0 THEN ma ELSE nullhdr%ma END))) AS nullhdr2
FROM (
SELECT schemaname,
tablename,
hdr,
ma,
bs,
SUM((1-null_frac)*avg_width) AS datawidth,
MAX(null_frac) AS maxfracsum,
hdr+(SELECT 1+count(*)/8 FROM pg_stats s2 WHERE null_frac<>0 AND s2.schemaname = s.schemaname AND s2.tablename = s.tablename) AS nullhdr
FROM pg_stats s, (
SELECT (
SELECT current_setting(''block_size'')::numeric) AS bs,
CASE WHEN substring(v,12,3) IN (''8.0'',''8.1'',''8.2'') THEN 27 ELSE 23 END AS hdr,
CASE WHEN v ~ ''mingw32'' THEN 8 ELSE 4 END AS ma
FROM (SELECT version() AS v) AS foo
) AS constants
GROUP BY 1,2,3,4,5
) AS foo
) AS rs
JOIN pg_class cc ON cc.relname = rs.tablename
JOIN pg_namespace nn ON cc.relnamespace = nn.oid AND nn.nspname = rs.schemaname AND nn.nspname <> ''information_schema''
LEFT JOIN pg_index i ON indrelid = cc.oid
LEFT JOIN pg_class c2 ON c2.oid = i.indexrelid
) AS sml
ORDER BY CASE WHEN relpages < otta THEN 0 ELSE bs*(sml.relpages-otta)::bigint END DESC;
4 changes: 4 additions & 0 deletions dotfiles/.psqlrc_aliases/db_size.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-- Retrieves the size of each database in the PostgreSQL instance.
SELECT datname, pg_size_pretty(pg_database_size(datname)) db_size
FROM pg_database
ORDER BY pg_database_size(datname);
6 changes: 6 additions & 0 deletions dotfiles/.psqlrc_aliases/index_size.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
SELECT relname AS name,
pg_size_pretty(sum(relpages*1024)) AS size
FROM pg_class
WHERE reltype = 0
GROUP BY relname
ORDER BY sum(relpages) DESC;
12 changes: 12 additions & 0 deletions dotfiles/.psqlrc_aliases/index_usage.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
SELECT * FROM (
SELECT stat.relname AS table,
stai.indexrelname AS index,
CASE stai.idx_scan WHEN 0 THEN ''Insufficient data'' ELSE (100 * stai.idx_scan / (stat.seq_scan + stai.idx_scan))::text || ''%'' END hit_rate,
CASE stat.idx_scan WHEN 0 THEN ''Insufficient data'' ELSE (100 * stat.idx_scan / (stat.seq_scan + stat.idx_scan))::text || ''%'' END all_index_hit_rate,
ARRAY(SELECT pg_get_indexdef(idx.indexrelid, k + 1, true) FROM generate_subscripts(idx.indkey, 1) AS k ORDER BY k) AS cols,
stat.n_live_tup rows_in_table
FROM pg_stat_user_indexes AS stai
JOIN pg_stat_user_tables AS stat ON stai.relid = stat.relid
JOIN pg_index AS idx ON (idx.indexrelid = stai.indexrelid)
) AS sub_inner
ORDER BY rows_in_table DESC, hit_rate ASC;
12 changes: 12 additions & 0 deletions dotfiles/.psqlrc_aliases/last_vacuum_analyze.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
-- Retrieves information about the last vacuum and analyze operations performed on tables.
SELECT schemaname,
relname,
last_vacuum,
last_autovacuum,
last_analyze,
last_autoanalyze,
pg_size_pretty(pg_total_relation_size('"' || schemaname || '"."' || relname || '"')) AS size
FROM pg_stat_all_tables
--ORDER BY last_autovacuum, last_autoanalyze;
--ORDER BY schemaname, relname;
ORDER BY pg_total_relation_size('"' || schemaname || '"."' || relname || '"') DESC;
11 changes: 11 additions & 0 deletions dotfiles/.psqlrc_aliases/locks.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
-- Retrieves information about blocked and blocking processes.
SELECT bl.pid AS blocked_pid,
a.usename AS blocked_user,
kl.pid AS blocking_pid,
ka.usename AS blocking_user,
a.query AS blocked_statement
FROM pg_catalog.pg_locks bl
JOIN pg_catalog.pg_stat_activity a ON bl.pid = a.pid
JOIN pg_catalog.pg_locks kl ON bl.transactionid = kl.transactionid AND bl.pid != kl.pid
JOIN pg_catalog.pg_stat_activity ka ON kl.pid = ka.pid
WHERE NOT bl.granted;
24 changes: 24 additions & 0 deletions dotfiles/.psqlrc_aliases/missing_indexes.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
-- Identifies foreign key constraints in PostgreSQL tables that might be missing indexes.
SELECT src_table,
dst_table,
fk_name,
pg_size_pretty(s_size) AS s_size,
pg_size_pretty(d_size) AS d_size,
d
FROM (
SELECT DISTINCT ON (1,2,3,4,5)
textin(regclassout(c.conrelid)) AS src_table,
textin(regclassout(c.confrelid)) AS dst_table,
c.conname AS fk_name,
pg_relation_size(c.conrelid) AS s_size,
pg_relation_size(c.confrelid) AS d_size,
array_upper(di.indkey::int[], 1) + 1 - array_upper(c.conkey::int[], 1) AS d
FROM pg_constraint c
LEFT JOIN pg_index di ON di.indrelid = c.conrelid AND array_to_string(di.indkey, '' '') ~ (''^'' || array_to_string(c.conkey, '' '') || ''( |$)'')
JOIN pg_stat_user_tables st ON st.relid = c.conrelid
WHERE c.contype = ''f''
ORDER BY 1,2,3,4,5,6 ASC
) mfk
WHERE mfk.d is distinct from 0
AND mfk.s_size > 1000000
ORDER BY mfk.s_size DESC, mfk.d DESC;
6 changes: 6 additions & 0 deletions dotfiles/.psqlrc_aliases/slow_queries.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
-- Shows slow queries.
SELECT (total_time / 1000 / 60) as total_minutes,
(total_time/calls) as average_time,
query
FROM pg_stat_statements
ORDER BY 1 DESC;
9 changes: 9 additions & 0 deletions dotfiles/.psqlrc_aliases/table_size.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-- Retrieves the sizes of all tables, with and without indexes/TOAST.
SELECT table_schema,
table_name,
pg_relation_size(quote_ident(table_schema) || '.' || quote_ident(table_name)) AS size,
pg_total_relation_size(quote_ident(table_schema) || '.' || quote_ident(table_name)) AS total_size
FROM information_schema.tables
WHERE table_type = 'BASE TABLE'
AND table_schema NOT IN ('information_schema', 'pg_catalog')
ORDER BY pg_total_relation_size(quote_ident(table_schema) || '.' || quote_ident(table_name)) DESC, table_schema, table_name;
15 changes: 15 additions & 0 deletions dotfiles/.psqlrc_aliases/trash_indexes.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
-- Identifies non-unique indexes on large tables that are rarely used.
SELECT s.schemaname AS sch,
s.relname AS rel,
s.indexrelname AS idx,
s.idx_scan AS scans,
pg_size_pretty(pg_relation_size(s.relid)) AS table_size,
pg_size_pretty(pg_relation_size(s.indexrelid)) AS index_size
FROM pg_stat_user_indexes s
JOIN pg_index i ON i.indexrelid = s.indexrelid
LEFT JOIN pg_constraint c ON i.indrelid = c.conrelid AND array_to_string(i.indkey, '' '') = array_to_string(c.conkey, '' '')
WHERE i.indisunique IS FALSE
AND pg_relation_size(s.relid) > 1000000
AND s.idx_scan < 100000
AND c.confrelid IS NULL
ORDER BY s.idx_scan ASC, pg_relation_size(s.relid) DESC;
25 changes: 25 additions & 0 deletions dotfiles/.psqlrc_aliases/uselesscol.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
-- Retrieves information about columns in PostgreSQL tables that might be considered "useless".
SELECT nspname,
relname,
attname,
typname,
(stanullfrac * 100)::int AS null_percent,
CASE WHEN stadistinct >= 0 THEN stadistinct
ELSE abs(stadistinct) * reltuples
END AS distinct,
CASE 1 WHEN stakind1 THEN stavalues1
WHEN stakind2 THEN stavalues2
END AS values
FROM pg_class c
JOIN pg_namespace ns ON ns.oid = relnamespace
JOIN pg_attribute ON c.oid = attrelid
JOIN pg_type t ON t.oid = atttypid
JOIN pg_statistic ON c.oid = starelid AND staattnum = attnum
WHERE nspname NOT LIKE E'pg\\_%'
AND nspname != 'information_schema'
AND relkind = 'r'
AND NOT attisdropped
AND attstattarget != 0
AND reltuples >= 100
AND stadistinct BETWEEN 0 AND 1
ORDER BY nspname, relname, attname;
9 changes: 9 additions & 0 deletions dotfiles/.psqlrc_aliases/waits.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-- Retrieves information about active queries in PostgreSQL that are currently waiting.
SELECT pg_stat_activity.pid,
pg_stat_activity.query,
pg_stat_activity.waiting,
now() - pg_stat_activity.query_start AS totaltime,
pg_stat_activity.backend_start
FROM pg_stat_activity
WHERE pg_stat_activity.query !~ '%IDLE%'::text
AND pg_stat_activity.waiting = true;

0 comments on commit cbe5a75

Please sign in to comment.